mirror of
https://github.com/micropython/micropython.git
synced 2025-12-25 22:30:12 +01:00
Compare commits
275 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
552f7c40a0 | ||
|
|
ad33e2465c | ||
|
|
31c1f1300e | ||
|
|
32444b759a | ||
|
|
5c670acb1f | ||
|
|
4c1a7e0d6a | ||
|
|
0fb17f6ef4 | ||
|
|
ca377b10de | ||
|
|
8d427b7ab7 | ||
|
|
c585ad1020 | ||
|
|
6b636738b2 | ||
|
|
23342c09ff | ||
|
|
91232d3850 | ||
|
|
ca3dbb8d8b | ||
|
|
66b060f3e6 | ||
|
|
444331c07f | ||
|
|
1f04336b23 | ||
|
|
425f952a1e | ||
|
|
220d21e1bf | ||
|
|
344e15b1ae | ||
|
|
6113eb2f33 | ||
|
|
e5bcbcdebd | ||
|
|
6d1f5070ce | ||
|
|
bd9c1ad601 | ||
|
|
8b77e3dd2f | ||
|
|
77089bebd4 | ||
|
|
05005f679e | ||
|
|
0b9ee86133 | ||
|
|
2e526ff1a1 | ||
|
|
8064892c9b | ||
|
|
b6e6b5277f | ||
|
|
962a5d50c9 | ||
|
|
d7f199465f | ||
|
|
73533247cb | ||
|
|
bf19541f46 | ||
|
|
0ab3fc3805 | ||
|
|
50149a5730 | ||
|
|
ff8dd3f486 | ||
|
|
50912e7f5d | ||
|
|
640e0b221e | ||
|
|
438b3d26b5 | ||
|
|
f1700a5154 | ||
|
|
51ef28a9d6 | ||
|
|
3926c72dd2 | ||
|
|
963a5a3e82 | ||
|
|
f12ea7c7ed | ||
|
|
0abb5609b0 | ||
|
|
2276eb8084 | ||
|
|
d7337f288e | ||
|
|
87bc8e2b3d | ||
|
|
c6b8750c14 | ||
|
|
d2d64f00fb | ||
|
|
65ef6b768c | ||
|
|
d95b519aa1 | ||
|
|
d9dc6fff21 | ||
|
|
bc47c287df | ||
|
|
1e1779eacf | ||
|
|
2127e9a844 | ||
|
|
c935d69f74 | ||
|
|
d6ed6702f7 | ||
|
|
4c81ba8015 | ||
|
|
dab1385177 | ||
|
|
d710cef661 | ||
|
|
a45b042e59 | ||
|
|
f41df1e611 | ||
|
|
5ebabcda41 | ||
|
|
d511a20a6b | ||
|
|
bbf5cd01e3 | ||
|
|
30d8a82220 | ||
|
|
abc1959e2c | ||
|
|
cd34207409 | ||
|
|
3dd1c0a88a | ||
|
|
0178aa9a11 | ||
|
|
b58da9420c | ||
|
|
131185a2b8 | ||
|
|
7630d9ca0e | ||
|
|
5b76e3b75e | ||
|
|
99dde4ed1f | ||
|
|
3f9f9cac75 | ||
|
|
708574b082 | ||
|
|
06e9cb688b | ||
|
|
a7bcb218fe | ||
|
|
99ab64ffd4 | ||
|
|
95836f8439 | ||
|
|
6942f80a8f | ||
|
|
e233a55a29 | ||
|
|
c38dc3ccc7 | ||
|
|
ec21405821 | ||
|
|
56e1f99ca1 | ||
|
|
01418e9690 | ||
|
|
ddd1e18801 | ||
|
|
7bfe4b21b9 | ||
|
|
58056b0f43 | ||
|
|
f5465b9eb0 | ||
|
|
5d48f234d2 | ||
|
|
a9a0862078 | ||
|
|
89deec0bab | ||
|
|
4a5895c4eb | ||
|
|
85e8e2ed5b | ||
|
|
3990dcfcd7 | ||
|
|
14fab60baf | ||
|
|
d2d0648ad0 | ||
|
|
7a53ac8ec2 | ||
|
|
c33ecb83ba | ||
|
|
5b7aa294e0 | ||
|
|
19b3fea6a8 | ||
|
|
115187f7ce | ||
|
|
afd6c8e1d2 | ||
|
|
181bfb6db2 | ||
|
|
c223df5113 | ||
|
|
3b51b3e90f | ||
|
|
7a0636e80a | ||
|
|
7ee91cf861 | ||
|
|
b4b10fd350 | ||
|
|
ad2307c92c | ||
|
|
d8bfd77ad5 | ||
|
|
b27c9876ea | ||
|
|
343ca1e63a | ||
|
|
51af362e31 | ||
|
|
ed3b20aae8 | ||
|
|
ff8e35b42e | ||
|
|
c114496641 | ||
|
|
ae58795c44 | ||
|
|
6fd4b36bc5 | ||
|
|
6e0b6d02db | ||
|
|
ffc96a901a | ||
|
|
fbfd3554fa | ||
|
|
8dec62a1a4 | ||
|
|
fd40a9c38e | ||
|
|
872a82970d | ||
|
|
8a2347723e | ||
|
|
0b2a60acbe | ||
|
|
fe7d542352 | ||
|
|
4ef4ffe1c5 | ||
|
|
c2e22d66da | ||
|
|
b68d98d61c | ||
|
|
2cf6dfa280 | ||
|
|
b36be5ff51 | ||
|
|
6d7e47087f | ||
|
|
3765ea419a | ||
|
|
51dfcb4bb7 | ||
|
|
db1ac360c3 | ||
|
|
8a8c1fc82f | ||
|
|
ebde3c694f | ||
|
|
ddbcc79550 | ||
|
|
ce5b5caf8c | ||
|
|
84e0cf0d21 | ||
|
|
7f23384d49 | ||
|
|
276159e5dd | ||
|
|
021dc44009 | ||
|
|
12340147b0 | ||
|
|
8422cac088 | ||
|
|
e0ac194f4f | ||
|
|
816a46a4ab | ||
|
|
2c75665445 | ||
|
|
8a2cc1c7e4 | ||
|
|
5f68094e10 | ||
|
|
f79cd6a233 | ||
|
|
12033df511 | ||
|
|
e3fa8278b4 | ||
|
|
9ddbe291c4 | ||
|
|
f89d659e3b | ||
|
|
23f1b5ff66 | ||
|
|
96e22154d7 | ||
|
|
361909e3ca | ||
|
|
1ee1785bed | ||
|
|
df103462dc | ||
|
|
749575097f | ||
|
|
1570eaf0e3 | ||
|
|
7690b13953 | ||
|
|
e2745b307b | ||
|
|
20236a8a99 | ||
|
|
6b755d827a | ||
|
|
c546b66bab | ||
|
|
83204f3406 | ||
|
|
e37dcaafb4 | ||
|
|
3b74c91684 | ||
|
|
8ab6f90674 | ||
|
|
343266ea51 | ||
|
|
c55a4d82cf | ||
|
|
7fdb8d78a4 | ||
|
|
f3a1d673de | ||
|
|
90cd6cd987 | ||
|
|
9c658b6afc | ||
|
|
a37656c132 | ||
|
|
74eb44c392 | ||
|
|
81836c28b3 | ||
|
|
01039b5bd8 | ||
|
|
584ba6762f | ||
|
|
b063b9b36d | ||
|
|
7b80d908bf | ||
|
|
9b561a7c0d | ||
|
|
4b60b45bfc | ||
|
|
6aaccc484c | ||
|
|
bf19586c53 | ||
|
|
6efa66f125 | ||
|
|
b47ea4eadd | ||
|
|
4fd7c1a2ac | ||
|
|
2870d85a11 | ||
|
|
978f4ca2e1 | ||
|
|
f5efefd5a0 | ||
|
|
6d3ae569cf | ||
|
|
2a3e2b9033 | ||
|
|
8427c5b76c | ||
|
|
f04329e93b | ||
|
|
6936f4626c | ||
|
|
c8b0229bc7 | ||
|
|
5cf7ac7309 | ||
|
|
9d944c7fb2 | ||
|
|
9642846d71 | ||
|
|
0078561303 | ||
|
|
7a4765dbeb | ||
|
|
b62371e8fb | ||
|
|
c0bc3bd736 | ||
|
|
83d27b0f0b | ||
|
|
138562ccd9 | ||
|
|
e181c0dc07 | ||
|
|
7764f163fa | ||
|
|
1ca28bd570 | ||
|
|
dbc7854355 | ||
|
|
f42b3c7599 | ||
|
|
5fba93a26b | ||
|
|
c33ce606cf | ||
|
|
f905145c6d | ||
|
|
184182d14c | ||
|
|
66a6caa307 | ||
|
|
5318cc028a | ||
|
|
7eb2317fa2 | ||
|
|
969a6b37bf | ||
|
|
d51107927d | ||
|
|
4140e19c8a | ||
|
|
e8487ea1be | ||
|
|
6c3fc74656 | ||
|
|
b4fe6e28eb | ||
|
|
78d702c300 | ||
|
|
e6e8ad8ab2 | ||
|
|
706955976c | ||
|
|
5deceb842d | ||
|
|
b66a31c42c | ||
|
|
008251180d | ||
|
|
46c3ab2004 | ||
|
|
d0caaadaee | ||
|
|
1f8a2f6623 | ||
|
|
9de6773237 | ||
|
|
d4f80f58b8 | ||
|
|
be6d8be91e | ||
|
|
451a087075 | ||
|
|
759cc9bcc8 | ||
|
|
a4c52c5a3d | ||
|
|
41c07d5b80 | ||
|
|
adf4c4cea8 | ||
|
|
c0b3d4540b | ||
|
|
29a1ec1bd6 | ||
|
|
d8f239263d | ||
|
|
32ef3a3517 | ||
|
|
3a5352b483 | ||
|
|
cd97a43f8d | ||
|
|
57c70d6073 | ||
|
|
578ea6d4a5 | ||
|
|
d8fd3103fa | ||
|
|
d96a916405 | ||
|
|
7f0699eedf | ||
|
|
6e8ff9cd68 | ||
|
|
17c5ce3727 | ||
|
|
1960475ed7 | ||
|
|
c7ca01ad96 | ||
|
|
d8c2b2a1c4 | ||
|
|
b2e731177e | ||
|
|
19fb1b4dd7 | ||
|
|
b395220ef0 | ||
|
|
7288403b9b | ||
|
|
3b603f29ec | ||
|
|
e636279fe0 | ||
|
|
bfdc205934 | ||
|
|
d96e6b14c9 |
@@ -7,15 +7,16 @@ before_script:
|
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-arm-none-eabi qemu-system mingw32
|
||||
- sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-multilib gcc-arm-none-eabi qemu-system mingw32
|
||||
# For teensy build
|
||||
- sudo apt-get install realpath
|
||||
|
||||
script:
|
||||
- make -C minimal test
|
||||
- make -C unix CC=gcc-4.7
|
||||
- make -C unix-cpy CC=gcc-4.7
|
||||
- make -C bare-arm
|
||||
- make -C qemu-arm
|
||||
- make -C qemu-arm test
|
||||
- make -C stmhal
|
||||
- make -C stmhal -B MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
|
||||
- make -C stmhal BOARD=STM32F4DISC
|
||||
@@ -27,3 +28,4 @@ script:
|
||||
|
||||
after_failure:
|
||||
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
||||
- (grep "FAIL" qemu-arm/build/console.out)
|
||||
|
||||
@@ -9,7 +9,7 @@ include ../py/py.mk
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
INC = -I.
|
||||
INC += -I$(PY_SRC)
|
||||
INC += -I..
|
||||
INC += -I$(BUILD)
|
||||
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||
|
||||
@@ -2,18 +2,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "parsehelper.h"
|
||||
#include "compile.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
#include "repl.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/parsehelper.h"
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/pfenv.h"
|
||||
|
||||
void do_str(const char *src) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
@@ -32,13 +26,13 @@ void do_str(const char *src) {
|
||||
}
|
||||
|
||||
// parse okay
|
||||
qstr source_name = mp_lexer_source_name(lex);
|
||||
qstr source_name = lex->source_name;
|
||||
mp_lexer_free(lex);
|
||||
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
|
||||
|
||||
if (mp_obj_is_exception_instance(module_fun)) {
|
||||
// compile error
|
||||
mp_obj_print_exception(module_fun);
|
||||
mp_obj_print_exception(printf_wrapper, NULL, module_fun);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -48,7 +42,7 @@ void do_str(const char *src) {
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception
|
||||
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
|
||||
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#define MICROPY_EMIT_X64 (0)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_COMP_MODULE_CONST (0)
|
||||
#define MICROPY_COMP_CONST (0)
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_ENABLE_GC (0)
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = [
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
#templates_path = ['templates']
|
||||
templates_path = ['templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
@@ -60,7 +60,7 @@ copyright = '2014, Damien P. George'
|
||||
# The short X.Y version.
|
||||
version = '1.3'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.3.7'
|
||||
release = '1.3.9'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@@ -144,7 +144,7 @@ else:
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
#html_static_path = ['static']
|
||||
html_static_path = ['static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
|
||||
@@ -46,6 +46,9 @@ The modes are:
|
||||
filesystem to its factory state, then boots in safe mode.
|
||||
|
||||
If your filesystem becomes corrupt, boot into mode 3 to fix it.
|
||||
If resetting the filesystem while plugged into your compute doesn't work,
|
||||
you can try doing the same procedure while the board is plugged into a USB
|
||||
charger, or other USB power supply without data connection.
|
||||
|
||||
Errors: flashing LEDs
|
||||
---------------------
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
.. _hardware_index:
|
||||
|
||||
The pyboard hardware
|
||||
====================
|
||||
|
||||
For the pyboard:
|
||||
|
||||
* `PYBv1.0 schematics and layout <http://micropython.org/resources/PYBv10b.pdf>`_ (2.4MiB PDF)
|
||||
* `PYBv1.0 metric dimensions <http://micropython.org/resources/PYBv10b-metric-dimensions.pdf>`_ (360KiB PDF)
|
||||
* `PYBv1.0 imperial dimensions <http://micropython.org/resources/PYBv10b-imperial-dimensions.pdf>`_ (360KiB PDF)
|
||||
|
||||
For the official skin modules:
|
||||
|
||||
* `LCD32MKv1.0 schematics <http://micropython.org/resources/LCD32MKv10-schematics.pdf>`_ (194KiB PDF)
|
||||
* `AMPv1.0 schematics <http://micropython.org/resources/AMPv10-schematics.pdf>`_ (209KiB PDF)
|
||||
|
||||
Datasheets for the components on the pyboard
|
||||
============================================
|
||||
|
||||
|
||||
@@ -38,9 +38,14 @@ it will fallback to loading the built-in ``ujson`` module.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
usocket.rst
|
||||
ubinascii.rst
|
||||
uctypes.rst
|
||||
uhashlib.rst
|
||||
uheapq.rst
|
||||
ujson.rst
|
||||
ure.rst
|
||||
usocket.rst
|
||||
uzlib.rst
|
||||
|
||||
Libraries specific to the pyboard
|
||||
---------------------------------
|
||||
|
||||
@@ -5,27 +5,116 @@
|
||||
.. module:: network
|
||||
:synopsis: network configuration
|
||||
|
||||
This module provides network drivers and routing configuration.
|
||||
This module provides network drivers and routing configuration. Network
|
||||
drivers for specific hardware are available within this module and are
|
||||
used to configure a hardware network interface. Configured interfaces
|
||||
are then available for use via the :mod:`socket` module.
|
||||
|
||||
For example::
|
||||
|
||||
class CC3k
|
||||
# configure a specific network interface
|
||||
# see below for examples of specific drivers
|
||||
import network
|
||||
nic = network.Driver(...)
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
import socket
|
||||
addr = socket.getaddrinfo('micropython.org', 80)[0][-1]
|
||||
s = socket.socket()
|
||||
s.connect(addr)
|
||||
s.send(b'GET / HTTP/1.1\r\nHost: micropython.org\r\n\r\n')
|
||||
data = s.recv(1000)
|
||||
s.close()
|
||||
|
||||
class CC3K
|
||||
==========
|
||||
|
||||
This class provides a driver for CC3000 wifi modules. Example usage::
|
||||
|
||||
import network
|
||||
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
|
||||
nic.connect('your-ssid', 'your-password')
|
||||
while not nic.isconnected():
|
||||
pyb.delay(50)
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
|
||||
For this example to work the CC3000 module must have the following connections:
|
||||
|
||||
- MOSI connected to Y8
|
||||
- MISO connected to Y7
|
||||
- CLK connected to Y6
|
||||
- CS connected to Y5
|
||||
- VBEN connected to Y4
|
||||
- IRQ connected to Y3
|
||||
|
||||
It is possible to use other SPI busses and other pins for CS, VBEN and IRQ.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: CC3k(spi, pin_cs, pin_en, pin_irq)
|
||||
.. class:: CC3K(spi, pin_cs, pin_en, pin_irq)
|
||||
|
||||
Initialise the CC3000 using the given SPI bus and pins and return a CC3k object.
|
||||
Create a CC3K driver object, initialise the CC3000 module using the given SPI bus
|
||||
and pins, and return the CC3K object.
|
||||
|
||||
Arguments are:
|
||||
|
||||
- ``spi`` is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the CC3000 is
|
||||
connected to (the MOSI, MISO and CLK pins).
|
||||
- ``pin_cs`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 CS pin.
|
||||
- ``pin_en`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 VBEN pin.
|
||||
- ``pin_irq`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 IRQ pin.
|
||||
|
||||
All of these objects will be initialised by the driver, so there is no need to
|
||||
initialise them yourself. For example, you can use::
|
||||
|
||||
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: cc3k.connect(ssid, key=None, \*, security=WPA2, bssid=None)
|
||||
|
||||
Connect to a wifi access point using the given SSID, and other security
|
||||
parameters.
|
||||
|
||||
class WIZnet5k
|
||||
.. method:: cc3k.disconnect()
|
||||
|
||||
Disconnect from the wifi access point.
|
||||
|
||||
.. method:: cc3k.isconnected()
|
||||
|
||||
Returns True if connected to a wifi access point and has a valid IP address,
|
||||
False otherwise.
|
||||
|
||||
.. method:: cc3k.ifconfig()
|
||||
|
||||
Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server,
|
||||
MAC address, SSID).
|
||||
|
||||
.. method:: cc3k.patch_version()
|
||||
|
||||
Return the version of the patch program (firmware) on the CC3000.
|
||||
|
||||
.. method:: cc3k.patch_program('pgm')
|
||||
|
||||
Upload the current firmware to the CC3000. You must pass 'pgm' as the first
|
||||
argument in order for the upload to proceed.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: CC3K.WEP
|
||||
.. data:: CC3K.WPA
|
||||
.. data:: CC3K.WPA2
|
||||
|
||||
security type to use
|
||||
|
||||
class WIZNET5K
|
||||
==============
|
||||
|
||||
This class allows you to control WIZnet5x00 Ethernet adaptors based on
|
||||
@@ -33,31 +122,56 @@ the W5200 and W5500 chipsets (only W5200 tested).
|
||||
|
||||
Example usage::
|
||||
|
||||
import wiznet5k
|
||||
w = wiznet5k.WIZnet5k()
|
||||
print(w.ipaddr())
|
||||
w.gethostbyname('micropython.org')
|
||||
s = w.socket()
|
||||
s.connect(('192.168.0.2', 8080))
|
||||
s.send('hello')
|
||||
print(s.recv(10))
|
||||
import network
|
||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
|
||||
For this example to work the WIZnet5x00 module must have the following connections:
|
||||
|
||||
- MOSI connected to X8
|
||||
- MISO connected to X7
|
||||
- SCLK connected to X6
|
||||
- nSS connected to X5
|
||||
- nRESET connected to X4
|
||||
|
||||
It is possible to use other SPI busses and other pins for nSS and nRESET.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: WIZnet5k(spi, pin_cs, pin_rst)
|
||||
.. class:: WIZNET5K(spi, pin_cs, pin_rst)
|
||||
|
||||
Create and return a WIZnet5k object.
|
||||
Create a WIZNET5K driver object, initialise the WIZnet5x00 module using the given
|
||||
SPI bus and pins, and return the WIZNET5K object.
|
||||
|
||||
Arguments are:
|
||||
|
||||
- ``spi`` is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the WIZnet5x00 is
|
||||
connected to (the MOSI, MISO and SCLK pins).
|
||||
- ``pin_cs`` is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nSS pin.
|
||||
- ``pin_rst`` is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nRESET pin.
|
||||
|
||||
All of these objects will be initialised by the driver, so there is no need to
|
||||
initialise them yourself. For example, you can use::
|
||||
|
||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: wiznet5k.ipaddr([(ip, subnet, gateway, dns)])
|
||||
.. method:: wiznet5k.ifconfig([(ip, subnet, gateway, dns)])
|
||||
|
||||
Get/set IP address, subnet mask, gateway and DNS.
|
||||
|
||||
When called with no arguments, this method returns a 4-tuple with the above information.
|
||||
|
||||
To set the above values, pass a 4-tuple with the required information. For example::
|
||||
|
||||
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
|
||||
|
||||
.. method:: wiznet5k.regs()
|
||||
|
||||
Dump WIZnet5k registers.
|
||||
Dump the WIZnet5x00 registers. Useful for debugging.
|
||||
|
||||
@@ -7,15 +7,12 @@ to connect the pyboard to a CAN bus you must use a CAN transceiver
|
||||
to convert the CAN logic signals from the pyboard to the correct
|
||||
voltage levels on the bus.
|
||||
|
||||
Note that this driver does not yet support filter configuration
|
||||
(it defaults to a single filter that lets through all messages),
|
||||
or bus timing configuration (except for setting the prescaler).
|
||||
|
||||
Example usage (works without anything connected)::
|
||||
|
||||
from pyb import CAN
|
||||
can = pyb.CAN(1, pyb.CAN.LOOPBACK)
|
||||
can.send('message!', 123) # send message to id 123
|
||||
can = CAN(1, CAN.LOOPBACK)
|
||||
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) # set a filter to receive messages with id=123, 124, 125 and 126
|
||||
can.send('message!', 123) # send a message with id 123
|
||||
can.recv(0) # receive message on FIFO 0
|
||||
|
||||
|
||||
@@ -35,7 +32,17 @@ Constructors
|
||||
- ``CAN(1)`` is on ``YA``: ``(RX, TX) = (Y3, Y4) = (PB8, PB9)``
|
||||
- ``CAN(2)`` is on ``YB``: ``(RX, TX) = (Y5, Y6) = (PB12, PB13)``
|
||||
|
||||
|
||||
Class Methods
|
||||
-------------
|
||||
.. method:: CAN.initfilterbanks(nr)
|
||||
|
||||
Reset and disable all filter banks and assign how many banks should be available for CAN(1).
|
||||
|
||||
STM32F405 has 28 filter banks that are shared between the two available CAN bus controllers.
|
||||
This function configures how many filter banks should be assigned to each. ``nr`` is the number of banks
|
||||
that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2).
|
||||
At boot, 14 banks are assigned to each controller.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
@@ -75,6 +82,37 @@ Methods
|
||||
|
||||
Turn off the CAN bus.
|
||||
|
||||
.. method:: can.setfilter(bank, mode, fifo, params)
|
||||
|
||||
Configure a filter bank:
|
||||
|
||||
- ``bank`` is the filter bank that is to be configured.
|
||||
- ``mode`` is the mode the filter should operate in.
|
||||
- ``fifo`` is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter.
|
||||
- ``params`` is an array of values the defines the filter. The contents of the array depends on the ``mode`` argument.
|
||||
|
||||
+-----------+---------------------------------------------------------+
|
||||
|``mode`` |contents of parameter array |
|
||||
+===========+=========================================================+
|
||||
|CAN.LIST16 |Four 16 bit ids that will be accepted |
|
||||
+-----------+---------------------------------------------------------+
|
||||
|CAN.LIST32 |Two 32 bit ids that will be accepted |
|
||||
+-----------+---------------------------------------------------------+
|
||||
|CAN.MASK16 |Two 16 bit id/mask pairs. E.g. (1, 3, 4, 4) |
|
||||
| | | The first pair, 1 and 3 will accept all ids |
|
||||
| | | that have bit 0 = 1 and bit 1 = 0. |
|
||||
| | | The second pair, 4 and 4, will accept all ids |
|
||||
| | | that have bit 2 = 1. |
|
||||
+-----------+---------------------------------------------------------+
|
||||
|CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.|
|
||||
+-----------+---------------------------------------------------------+
|
||||
|
||||
.. method:: can.clearfilter(bank)
|
||||
|
||||
Clear and disables a filter bank:
|
||||
|
||||
- ``bank`` is the filter bank that is to be cleared.
|
||||
|
||||
.. method:: can.any(fifo)
|
||||
|
||||
Return ``True`` if any message waiting on the FIFO, else ``False``.
|
||||
@@ -98,7 +136,6 @@ Methods
|
||||
|
||||
Return value: ``None``.
|
||||
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
@@ -108,3 +145,10 @@ Constants
|
||||
.. data:: CAN.SILENT_LOOPBACK
|
||||
|
||||
the mode of the CAN bus
|
||||
|
||||
.. data:: CAN.LIST16
|
||||
.. data:: CAN.MASK16
|
||||
.. data:: CAN.LIST32
|
||||
.. data:: CAN.MASK32
|
||||
|
||||
the operation mode of a filter
|
||||
|
||||
@@ -53,7 +53,7 @@ Methods
|
||||
|
||||
Generate a triangle wave. The value on the DAC output changes at
|
||||
the given frequency, and the frequence of the repeating triangle wave
|
||||
itself is 256 (or 1024, need to check) times smaller.
|
||||
itself is 2048 times smaller.
|
||||
|
||||
.. method:: dac.write(value)
|
||||
|
||||
|
||||
@@ -31,8 +31,9 @@ Methods
|
||||
|
||||
.. method:: led.on()
|
||||
|
||||
Turn the LED on.
|
||||
Turn the LED on, to maximum intensity.
|
||||
|
||||
.. method:: led.toggle()
|
||||
|
||||
Toggle the LED between on and off.
|
||||
Toggle the LED between on (maximum intensity) and off. If the LED is at
|
||||
non-zero intensity then it is considered "on" and toggle will turn it off.
|
||||
|
||||
@@ -52,12 +52,29 @@ Methods
|
||||
|
||||
Turn off the SPI bus.
|
||||
|
||||
.. method:: spi.init(mode, baudrate=328125, \*, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
|
||||
.. method:: spi.init(mode, baudrate=328125, \*, prescaler, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
|
||||
|
||||
Initialise the SPI bus with the given parameters:
|
||||
|
||||
- ``mode`` must be either ``SPI.MASTER`` or ``SPI.SLAVE``.
|
||||
- ``baudrate`` is the SCK clock rate (only sensible for a master).
|
||||
- ``prescaler`` is the prescaler to use to derive SCK from the APB bus frequency;
|
||||
use of ``prescaler`` overrides ``baudrate``.
|
||||
- ``polarity`` can be 0 or 1, and is the level the idle clock line sits at.
|
||||
- ``phase`` can be 0 or 1 to sample data on the first or second clock edge
|
||||
respectively.
|
||||
- ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``.
|
||||
- ``crc`` can be None for no CRC, or a polynomial specifier.
|
||||
|
||||
Note that the SPI clock frequency will not always be the requested baudrate.
|
||||
The hardware only supports baudrates that are the APB bus frequency
|
||||
(see :meth:`pyb.freq`) divided by a prescaler, which can be 2, 4, 8, 16, 32,
|
||||
64, 128 or 256. SPI(1) is on AHB2, and SPI(2) is on AHB1. For precise
|
||||
control over the SPI clock frequency, specify ``prescaler`` instead of
|
||||
``baudrate``.
|
||||
|
||||
Printing the SPI object will show you the computed baudrate and the chosen
|
||||
prescaler.
|
||||
|
||||
.. method:: spi.recv(recv, \*, timeout=5000)
|
||||
|
||||
|
||||
@@ -1,15 +1,37 @@
|
||||
.. _pyb.Servo:
|
||||
|
||||
class Servo -- 3-wire hobby servo driver
|
||||
========================================
|
||||
|
||||
Servo controls standard hobby servos with 3-wires (ground, power, signal).
|
||||
Servo objects control standard hobby servo motors with 3-wires (ground, power,
|
||||
signal). There are 4 positions on the pyboard where these motors can be plugged
|
||||
in: pins X1 through X4 are the signal pins, and next to them are 4 sets of power
|
||||
and ground pins.
|
||||
|
||||
Example usage::
|
||||
|
||||
import pyb
|
||||
|
||||
s1 = pyb.Servo(1) # create a servo object on position X1
|
||||
s2 = pyb.Servo(2) # create a servo object on position X2
|
||||
|
||||
s1.angle(45) # move servo 1 to 45 degrees
|
||||
s2.angle(0) # move servo 2 to 0 degrees
|
||||
|
||||
# move servo1 and servo2 synchronously, taking 1500ms
|
||||
s1.angle(-60, 1500)
|
||||
s2.angle(30, 1500)
|
||||
|
||||
.. note:: The Servo objects use Timer(5) to produce the PWM output. You can
|
||||
use Timer(5) for Servo control, or your own purposes, but not both at the
|
||||
same time.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.Servo(id)
|
||||
|
||||
Create a servo object. ``id`` is 1-4.
|
||||
Create a servo object. ``id`` is 1-4, and corresponds to pins X1 through X4.
|
||||
|
||||
|
||||
Methods
|
||||
@@ -17,22 +39,41 @@ Methods
|
||||
|
||||
.. method:: servo.angle([angle, time=0])
|
||||
|
||||
Get or set the angle of the servo.
|
||||
|
||||
If no arguments are given, this function returns the current angle.
|
||||
|
||||
If arguments are given, this function sets the angle of the servo:
|
||||
|
||||
- ``angle`` is the angle to move to in degrees.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified angle.
|
||||
|
||||
.. method:: servo.calibration([pulse_min, pulse_max, pulse_centre, [pulse_angle_90, pulse_speed_100]])
|
||||
|
||||
Get or set the calibration of the servo timing.
|
||||
|
||||
.. method:: servo.pulse_width([value])
|
||||
|
||||
Get or set the pulse width in milliseconds.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified
|
||||
angle. If omitted, then the servo moves as quickly as possible to its
|
||||
new position.
|
||||
|
||||
.. method:: servo.speed([speed, time=0])
|
||||
|
||||
Get or set the speed of a continuous rotation servo.
|
||||
|
||||
- ``speed`` is the speed to move to change to, between -100 and 100.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified speed.
|
||||
If no arguments are given, this function returns the current speed.
|
||||
|
||||
If arguments are given, this function sets the speed of the servo:
|
||||
|
||||
- ``speed`` is the speed to change to, between -100 and 100.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified
|
||||
speed. If omitted, then the servo accelerates as quickly as possible.
|
||||
|
||||
.. method:: servo.pulse_width([value])
|
||||
|
||||
If no arguments are given, this function returns the current raw pulse-width
|
||||
value.
|
||||
|
||||
If an argument is given, this function sets the raw pulse-width value.
|
||||
|
||||
.. method:: servo.calibration([pulse_min, pulse_max, pulse_centre, [pulse_angle_90, pulse_speed_100]])
|
||||
|
||||
If no arguments are given, this function returns the current calibration
|
||||
data, as a 5-tuple.
|
||||
|
||||
If arguments are given, this function sets the timing calibration:
|
||||
|
||||
- ``pulse_min`` is the minimum allowed pulse width.
|
||||
- ``pulse_max`` is the maximum allowed pulse width.
|
||||
- ``pulse_centre`` is the pulse width corresponding to the centre/zero position.
|
||||
- ``pulse_angle_90`` is the pulse width corresponding to 90 degrees.
|
||||
- ``pulse_speed_100`` is the pulse width corresponding to a speed of 100.
|
||||
|
||||
@@ -17,6 +17,15 @@ Constructors
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: usb_vcp.setinterrupt(chr)
|
||||
|
||||
Set the character which interrupts running Python code. This is set
|
||||
to 3 (CTRL-C) by default, and when a CTRL-C character is received over
|
||||
the USB VCP port, a KeyboardInterrupt exception is raised.
|
||||
|
||||
Set to -1 to disable this interrupt feature. This is useful when you
|
||||
want to send raw bytes over the USB VCP port.
|
||||
|
||||
.. method:: usb_vcp.any()
|
||||
|
||||
Return ``True`` if any characters waiting, else ``False``.
|
||||
|
||||
@@ -93,26 +93,42 @@ Interrupt related functions
|
||||
Power related functions
|
||||
-----------------------
|
||||
|
||||
.. function:: freq([sys_freq])
|
||||
.. function:: freq([sysclk[, hclk[, pclk1[, pclk2]]]])
|
||||
|
||||
If given no arguments, returns a tuple of clock frequencies:
|
||||
(SYSCLK, HCLK, PCLK1, PCLK2).
|
||||
|
||||
If given an argument, sets the system frequency to that value in Hz.
|
||||
Eg freq(120000000) gives 120MHz. Note that not all values are
|
||||
supported and the largest supported frequency not greater than
|
||||
the given sys_freq will be selected.
|
||||
(sysclk, hclk, pclk1, pclk2).
|
||||
These correspond to:
|
||||
|
||||
Supported frequencies are (in MHz): 8, 16, 24, 30, 32, 36, 40, 42, 48,
|
||||
- sysclk: frequency of the CPU
|
||||
- hclk: frequency of the AHB bus, core memory and DMA
|
||||
- pclk1: frequency of the APB1 bus
|
||||
- pclk2: frequency of the APB2 bus
|
||||
|
||||
If given any arguments then the function sets the frequency of the CPU,
|
||||
and the busses if additional arguments are given. Frequencies are given in
|
||||
Hz. Eg freq(120000000) sets sysclk (the CPU frequency) to 120MHz. Note that
|
||||
not all values are supported and the largest supported frequency not greater
|
||||
than the given value will be selected.
|
||||
|
||||
Supported sysclk frequencies are (in MHz): 8, 16, 24, 30, 32, 36, 40, 42, 48,
|
||||
54, 56, 60, 64, 72, 84, 96, 108, 120, 144, 168.
|
||||
|
||||
The maximum frequency of hclk is 168MHz, of pclk1 is 42MHz, and of pclk2 is
|
||||
84MHz. Be sure not to set frequencies above these values.
|
||||
|
||||
The hclk, pclk1 and pclk2 frequencies are derived from the sysclk frequency
|
||||
using a prescaler (divider). Supported prescalers for hclk are: 1, 2, 4, 8,
|
||||
16, 64, 128, 256, 512. Supported prescalers for pclk1 and pclk2 are: 1, 2,
|
||||
4, 8. A prescaler will be chosen to best match the requested frequency.
|
||||
|
||||
A sysclk frequency of
|
||||
8MHz uses the HSE (external crystal) directly and 16MHz uses the HSI
|
||||
(internal oscillator) directly. The higher frequencies use the HSE to
|
||||
drive the PLL (phase locked loop), and then use the output of the PLL.
|
||||
|
||||
Note that if you change the frequency while the USB is enabled then
|
||||
the USB may become unreliable. It is best to change the frequency
|
||||
in boot.py, before the USB peripheral is started. Also note that
|
||||
in boot.py, before the USB peripheral is started. Also note that sysclk
|
||||
frequencies below 36MHz do not allow the USB to function correctly.
|
||||
|
||||
.. function:: wfi()
|
||||
@@ -142,6 +158,37 @@ Miscellaneous functions
|
||||
|
||||
Print out lots of information about the board.
|
||||
|
||||
.. function:: mount(device, mountpoint, \*, readonly=False, mkfs=False)
|
||||
|
||||
Mount a block device and make it available as part of the filesystem.
|
||||
``device`` must be an object that provides the block protocol:
|
||||
|
||||
- ``readblocks(self, blocknum, buf)``
|
||||
- ``writeblocks(self, blocknum, buf)`` (optional)
|
||||
- ``count(self)``
|
||||
- ``sync(self)`` (optional)
|
||||
|
||||
``readblocks`` and ``writeblocks`` should copy data between ``buf`` and
|
||||
the block device, starting from block number ``blocknum`` on the device.
|
||||
``buf`` will be a bytearray with length a multiple of 512. If
|
||||
``writeblocks`` is not defined then the device is mounted read-only.
|
||||
The return value of these two functions is ignored.
|
||||
|
||||
``count`` should return the number of blocks available on the device.
|
||||
``sync``, if implemented, should sync the data on the device.
|
||||
|
||||
The parameter ``mountpoint`` is the location in the root of the filesystem
|
||||
to mount the device. It must begin with a forward-slash.
|
||||
|
||||
If ``readonly`` is ``True``, then the device is mounted read-only,
|
||||
otherwise it is mounted read-write.
|
||||
|
||||
If ``mkfs`` is ``True``, then a new filesystem is created if one does not
|
||||
already exist.
|
||||
|
||||
To unmount a device, pass ``None`` as the device and the mount location
|
||||
as ``mountpoint``.
|
||||
|
||||
.. function:: repl_uart(uart)
|
||||
|
||||
Get or set the UART object that the REPL is repeated on.
|
||||
|
||||
@@ -12,6 +12,16 @@ Functions
|
||||
Raise a ``SystemExit`` exception. If an argument is given, it is the
|
||||
value given to ``SystemExit``.
|
||||
|
||||
.. function:: print_exception(exc, [file])
|
||||
|
||||
Print exception with a traceback to a file-like object ``file`` (or
|
||||
``sys.stdout`` by default).
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
This function appears in the ``traceback`` module in CPython.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
@@ -29,7 +39,9 @@ Constants
|
||||
|
||||
.. data:: platform
|
||||
|
||||
the platform that Micro Python is running on
|
||||
The platform that Micro Python is running on. This is "pyboard" on the
|
||||
pyboard and provides a robust way of determining if a script is running
|
||||
on the pyboard or not.
|
||||
|
||||
.. data:: stderr
|
||||
|
||||
|
||||
15
docs/library/ubinascii.rst
Normal file
15
docs/library/ubinascii.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
:mod:`ubinascii` -- binary/ASCII conversions
|
||||
============================================
|
||||
|
||||
.. module:: ubinascii
|
||||
:synopsis: binary/ASCII conversions
|
||||
|
||||
This module implements conversions between binary data and various
|
||||
encodings of it in ASCII form (in both directions).
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: hexlify(data)
|
||||
|
||||
Convert binary data to hexadecimal representation. Return bytes string.
|
||||
138
docs/library/uctypes.rst
Normal file
138
docs/library/uctypes.rst
Normal file
@@ -0,0 +1,138 @@
|
||||
:mod:`uctypes` -- access C structures
|
||||
=====================================
|
||||
|
||||
.. module:: uctypes
|
||||
:synopsis: access C structures
|
||||
|
||||
This module implements "foreign data interface" for MicroPython. The idea
|
||||
behind it is similar to CPython's ``ctypes`` modules, but actual API is
|
||||
different, steamlined and optimized for small size.
|
||||
|
||||
Defining structure layout
|
||||
-------------------------
|
||||
|
||||
Structure layout is defined by a "descriptor" - a Python dictionary which
|
||||
encodes field names as keys and other properties required to access them as
|
||||
an associated values. Currently, uctypes requires explicit specification of
|
||||
offsets for each field. Offset are given in bytes from structure start.
|
||||
|
||||
Following are encoding examples for various field types:
|
||||
|
||||
Scalar types::
|
||||
|
||||
"field_name": uctypes.UINT32 | 0
|
||||
|
||||
in other words, value is scalar type identifier ORed with field offset
|
||||
(in bytes) from the start of the structure.
|
||||
|
||||
Recursive structures::
|
||||
|
||||
"sub": (2, {
|
||||
"b0": uctypes.UINT8 | 0,
|
||||
"b1": uctypes.UINT8 | 1,
|
||||
})
|
||||
|
||||
i.e. value is a 2-tuple, first element of which is offset, and second is
|
||||
a structure descriptor dictionary (note: offsets in recursive descriptors
|
||||
are relative to a structure it defines).
|
||||
|
||||
Arrays of primitive types::
|
||||
|
||||
"arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 2),
|
||||
|
||||
i.e. value is a 2-tuple, first element of which is ARRAY flag ORed
|
||||
with offset, and second is scalar element type ORed number of elements
|
||||
in array.
|
||||
|
||||
Arrays of aggregate types::
|
||||
|
||||
"arr2": (uctypes.ARRAY | 0, 2, {"b": uctypes.UINT8 | 0}),
|
||||
|
||||
i.e. value is a 3-tuple, first element of which is ARRAY flag ORed
|
||||
with offset, second is a number of elements in array, and third is
|
||||
descriptor of element type.
|
||||
|
||||
Pointer to a primitive type::
|
||||
|
||||
"ptr": (uctypes.PTR | 0, uctypes.UINT8),
|
||||
|
||||
i.e. value is a 2-tuple, first element of which is PTR flag ORed
|
||||
with offset, and second is scalar element type.
|
||||
|
||||
Pointer to aggregate type::
|
||||
|
||||
"ptr2": (uctypes.PTR | 0, {"b": uctypes.UINT8 | 0}),
|
||||
|
||||
i.e. value is a 2-tuple, first element of which is PTR flag ORed
|
||||
with offset, second is descriptor of type pointed to.
|
||||
|
||||
Bitfields::
|
||||
|
||||
"bitf0": uctypes.BFUINT16 | 0 | 0 << uctypes.BF_POS | 8 << uctypes.BF_LEN,
|
||||
|
||||
i.e. value is type of scalar value containing given bitfield (typenames are
|
||||
similar to scalar types, but prefixes with "BF"), ORed with offset for
|
||||
scalar value containing the bitfield, and further ORed with values for
|
||||
bit offset and bit length of the bitfield within scalar value, shifted by
|
||||
BF_POS and BF_LEN positions, respectively. Bitfield position is counted
|
||||
from the least significant bit, and is the number of right-most bit of a
|
||||
field (in other words, it's a number of bits a scalar needs to be shifted
|
||||
right to extra the bitfield).
|
||||
|
||||
In the example above, first UINT16 value will be extracted at offset 0
|
||||
(this detail may be important when accessing hardware registers, where
|
||||
particular access size and alignment are required), and then bitfield
|
||||
whose rightmost bit is least-significant bit of this UINT16, and length
|
||||
is 8 bits, will be extracted - effectively, this will access
|
||||
least-significant byte of UINT16.
|
||||
|
||||
Note that bitfield operations are independent of target byte endianness,
|
||||
in particular, example above will access least-significant byte of UINT16
|
||||
in both little- and big-endian structures. But it depends on the least
|
||||
significant bit being numbered 0. Some targets may use different
|
||||
numbering in their native ABI, but ``uctypes`` always uses normalized
|
||||
numbering described above.
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. class:: struct(descriptor, layout_type)
|
||||
|
||||
Create a "foreign data structure" object based on its descriptor (encoded
|
||||
as a dictionary) and layout type.
|
||||
|
||||
.. data:: LITTLE_ENDIAN
|
||||
|
||||
Little-endian packed structure. (Packed means that every field occupies
|
||||
exactly many bytes as defined in the descriptor, i.e. alignment is 1).
|
||||
|
||||
.. data:: BIG_ENDIAN
|
||||
|
||||
Big-endian packed structure.
|
||||
|
||||
.. data:: NATIVE
|
||||
|
||||
Native structure - with data endianness and alignment conforming to
|
||||
the target ABI.
|
||||
|
||||
(to be continued)
|
||||
|
||||
Structure objects
|
||||
-----------------
|
||||
|
||||
Structure objects allow accessing individual fields using standard dot
|
||||
notation: ``my_struct.field1``. If a field is of scalar type, getting
|
||||
it will produce primitive value (Python integer or float) corresponding
|
||||
to value contained in a field. Scalar field can also be assigned to.
|
||||
|
||||
If a field is an array, its individual elements can be accessed with
|
||||
standard subscript operator - both read and assigned to.
|
||||
|
||||
If a field is a pointer, it can be dereferenced using ``[0]`` syntax
|
||||
(corresponding to C ``*`` operator, though ``[0]`` works in C too).
|
||||
Subscripting pointer with other integer values but 0 are supported too,
|
||||
with the same semantics as in C.
|
||||
|
||||
Summing up, accessing structure fields generally follows C syntax,
|
||||
except for pointer derefence, you need to use ``[0]`` operator instead
|
||||
of ``*``.
|
||||
37
docs/library/uhashlib.rst
Normal file
37
docs/library/uhashlib.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
:mod:`uhashlib` -- hashing algorithm
|
||||
====================================
|
||||
|
||||
.. module:: uhashlib
|
||||
:synopsis: hashing algorithm
|
||||
|
||||
This module implements binary data hashing algorithms. Currently, it
|
||||
implements SHA256 algorithm. Choosing SHA256 was a deliberate choice,
|
||||
as a modern, cryptographically secure algorithm. This means that a
|
||||
single algorithm can cover both usecases of "any hash algorithm" and
|
||||
security-related usage, and thus save space omitting legacy algorithms
|
||||
like MD5 or SHA1.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: uhashlib.sha256([data])
|
||||
|
||||
Create a hasher object and optionally feed ``data`` into it.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: sha256.update(data)
|
||||
|
||||
Feed more binary data into hash.
|
||||
|
||||
.. method:: sha256.digest()
|
||||
|
||||
Return hash for all data passed thru hash, as a bytes object. After this
|
||||
method is called, more data cannot be fed into hash any longer.
|
||||
|
||||
.. method:: sha256.hexdigest()
|
||||
|
||||
This method is NOT implemented. Use ``ubinascii.hexlify(sha256.digest())``
|
||||
to achieve similar effect.
|
||||
82
docs/library/ure.rst
Normal file
82
docs/library/ure.rst
Normal file
@@ -0,0 +1,82 @@
|
||||
:mod:`ure` -- regular expressions
|
||||
=================================
|
||||
|
||||
.. module:: ure
|
||||
:synopsis: regular expressions
|
||||
|
||||
This module implements regular expression operations. Regular expression
|
||||
syntax supported is a subset of CPython ``re`` module (and actually is
|
||||
a subset of POSIX extended regular expressions).
|
||||
|
||||
Supported operators are:
|
||||
|
||||
``'.'``
|
||||
Match any character.
|
||||
|
||||
``'[]'``
|
||||
Match set of characters. Individual characters and ranges are supported.
|
||||
|
||||
``'^'``
|
||||
|
||||
``'$'``
|
||||
|
||||
``'?'``
|
||||
|
||||
``'*'``
|
||||
|
||||
``'+'``
|
||||
|
||||
``'??'``
|
||||
|
||||
``'*?'``
|
||||
|
||||
``'+?'``
|
||||
|
||||
Counted repetitions (``{m,n}``), more advanced assertions, names groups,
|
||||
etc. are not supported.
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: compile(regex)
|
||||
|
||||
Compile regular expression, return ``regex`` object.
|
||||
|
||||
.. function:: match(regex, string)
|
||||
|
||||
Match ``regex`` against ``string``. Match always happens from starting
|
||||
position in a string.
|
||||
|
||||
.. function:: search(regex, string)
|
||||
|
||||
Search ``regex`` in a ``string``. Unlike ``match``, this will search
|
||||
string for first position which matches regex (which still may be
|
||||
0 if regex is anchored).
|
||||
|
||||
.. data:: DEBUG
|
||||
|
||||
Flag value, display debug information about compiled expression.
|
||||
|
||||
|
||||
Regex objects
|
||||
-------------
|
||||
|
||||
Compiled regular expression. Instances of this class are created using
|
||||
``ure.compile()``.
|
||||
|
||||
.. method:: regex.match(string)
|
||||
|
||||
.. method:: regex.search(string)
|
||||
|
||||
.. method:: regex.split(string, max_split=-1)
|
||||
|
||||
|
||||
Match objects
|
||||
-------------
|
||||
|
||||
Match objects as returned by ``match()`` and ``search()`` methods.
|
||||
|
||||
.. method:: match.group([index])
|
||||
|
||||
Only numeric groups are supported.
|
||||
16
docs/library/uzlib.rst
Normal file
16
docs/library/uzlib.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
:mod:`uzlib` -- zlib decompression
|
||||
==================================
|
||||
|
||||
.. module:: uzlib
|
||||
:synopsis: zlib decompression
|
||||
|
||||
This modules allows to decompress binary data compressed with DEFLATE
|
||||
algorithm (commonly used in zlib library and gzip archiver). Compression
|
||||
is not yet implemented.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: decompress(data)
|
||||
|
||||
Return decompressed data as bytes.
|
||||
@@ -48,6 +48,18 @@ See :ref:`pyb.Pin <pyb.Pin>`. ::
|
||||
p_in = Pin('X2', Pin.IN, Pin.PULL_UP)
|
||||
p_in.value() # get value, 0 or 1
|
||||
|
||||
Servo control
|
||||
-------------
|
||||
|
||||
See :ref:`pyb.Servo <pyb.Servo>`. ::
|
||||
|
||||
from pyb import Servo
|
||||
|
||||
s1 = Servo(1) # servo on position 1 (X1, VIN, GND)
|
||||
s1.angle(45) # move to 45 degrees
|
||||
s1.angle(-60, 1500) # move to -60 degrees in 1500ms
|
||||
s1.speed(50) # for continuous rotation servos
|
||||
|
||||
External interrupts
|
||||
-------------------
|
||||
|
||||
|
||||
9
docs/readthedocs/settings/local_settings.py
Normal file
9
docs/readthedocs/settings/local_settings.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import os
|
||||
|
||||
# Directory that the project lives in, aka ../..
|
||||
SITE_ROOT = '/'.join(os.path.dirname(__file__).split('/')[0:-2])
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
"%s/templates/" % SITE_ROOT, # Your custom template directory, before the RTD one to override it.
|
||||
"%s/readthedocs/templates/" % SITE_ROOT, # Default RTD template dir
|
||||
)
|
||||
10
docs/static/customstyle.css
vendored
Normal file
10
docs/static/customstyle.css
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/* custom CSS for Micro Python docs
|
||||
*/
|
||||
|
||||
.admonition-difference-to-cpython {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.admonition-difference-to-cpython .admonition-title {
|
||||
margin: 4px;
|
||||
}
|
||||
2
docs/templates/layout.html
vendored
Normal file
2
docs/templates/layout.html
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
{% extends "!layout.html" %}
|
||||
{% set css_files = css_files + ["_static/customstyle.css"] %}
|
||||
@@ -17,6 +17,8 @@ The following video shows how to solder the headers, microphone and speaker onto
|
||||
|
||||
<iframe style="margin-left:3em;" width="560" height="315" src="http://www.youtube.com/embed/fjB1DuZRveo?rel=0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
For circuit schematics and datasheets for the components on the skin see :ref:`hardware_index`.
|
||||
|
||||
Example code
|
||||
------------
|
||||
|
||||
@@ -53,9 +55,13 @@ For example::
|
||||
You can also play WAV files using the Python ``wave`` module. You can get
|
||||
the wave module `here <http://micropython.org/resources/examples/wave.py>`_ and you will also need
|
||||
the chunk module available `here <http://micropython.org/resources/examples/chunk.py>`_. Put these
|
||||
on your pyboard (either on the flash or the SD card in the top-level
|
||||
directory). You will need an 8-bit WAV file to play, such as
|
||||
`this one <http://micropython.org/resources/examples/test.wav>`_. Then you can do::
|
||||
on your pyboard (either on the flash or the SD card in the top-level directory). You will need an
|
||||
8-bit WAV file to play, such as `this one <http://micropython.org/resources/examples/test.wav>`_,
|
||||
or to convert any file you have with the command::
|
||||
|
||||
avconv -i original.wav -ar 22050 -codec pcm_u8 test.wav
|
||||
|
||||
Then you can do::
|
||||
|
||||
>>> import wave
|
||||
>>> from pyb import DAC
|
||||
|
||||
@@ -18,6 +18,8 @@ At the end of the video, it shows you how to correctly connect the LCD skin to t
|
||||
|
||||
<iframe style="margin-left:3em;" width="560" height="315" src="http://www.youtube.com/embed/PowCzdLYbFM?rel=0" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
For circuit schematics and datasheets for the components on the skin see :ref:`hardware_index`.
|
||||
|
||||
Using the LCD
|
||||
-------------
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ Next we will set up an infinite loop that cycles through each of the LEDs turnin
|
||||
leds[n].toggle()
|
||||
pyb.delay(50)
|
||||
|
||||
Here, n keeps track of the current LED and every time the loop is executed we cycle to the next n (the % sign is a modulus operator that keeps n between 0 and 4.) Then we access the nth LED and toggle it. If you run this you should see each of the LEDs turning on then all turning off again in sequence.
|
||||
Here, n keeps track of the current LED and every time the loop is executed we cycle to the next n (the % sign is a modulus operator that keeps n between 0 and 3.) Then we access the nth LED and toggle it. If you run this you should see each of the LEDs turning on then all turning off again in sequence.
|
||||
|
||||
One problem you might find is that if you stop the script and then start it again that the LEDs are stuck on from the previous run, ruining our carefully choreographed disco. We can fix this by turning all the LEDs off when we initialise the script and then using a try/finally block. When you press CTRL-C, Micro Python generates a VCPInterrupt exception. Exceptions normally mean something has gone wrong and you can use a try: command to "catch" an exception. In this case it is just the user interrupting the script, so we don't need to catch the error but just tell Micro Python what to do when we exit. The finally block does this, and we use it to make sure all the LEDs are off. The full code is::
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ It's as simple as::
|
||||
import select
|
||||
|
||||
def pass_through(usb, uart):
|
||||
usb.setinterrupt(-1)
|
||||
while True:
|
||||
select.select([usb, uart], [], [])
|
||||
if usb.any():
|
||||
|
||||
@@ -23,6 +23,9 @@ then select the option to find the driver manually (don't use Windows auto updat
|
||||
navigate to the pyboard's USB drive, and select that. It should then install.
|
||||
After installing, go back to the Device Manager to find the installed pyboard,
|
||||
and see which COM port it is (eg COM4).
|
||||
More comprehensive instructions can be found in the
|
||||
`Guide for pyboard on Windows (PDF) <http://micropython.org/resources/Micro-Python-Windows-setup.pdf>`_.
|
||||
Please consult this guide if you are having problems installing the driver.
|
||||
|
||||
You now need to run your terminal program. You can use HyperTerminal if you
|
||||
have it installed, or download the free program PuTTY:
|
||||
|
||||
@@ -34,13 +34,9 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "pin.h"
|
||||
#include "led.h"
|
||||
#include "extint.h"
|
||||
@@ -177,7 +173,7 @@ void SpiOpen(gcSpiHandleRx pfRxHandler)
|
||||
CS_HIGH();
|
||||
|
||||
// register EXTI
|
||||
extint_register((mp_obj_t)PIN_IRQ, GPIO_MODE_IT_FALLING, GPIO_PULLUP, (mp_obj_t)&irq_callback_obj, true, NULL);
|
||||
extint_register((mp_obj_t)PIN_IRQ, GPIO_MODE_IT_FALLING, GPIO_PULLUP, (mp_obj_t)&irq_callback_obj, true);
|
||||
extint_enable(PIN_IRQ->pin);
|
||||
|
||||
DEBUG_printf("SpiOpen finished; IRQ.pin=%d IRQ_LINE=%d\n", PIN_IRQ->pin, PIN_IRQ->pin);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""NRF24L01 driver for Micro Python"""
|
||||
"""NRF24L01 driver for Micro Python
|
||||
"""
|
||||
|
||||
import pyb
|
||||
|
||||
@@ -10,7 +11,6 @@ SETUP_RETR = const(0x04)
|
||||
RF_CH = const(0x05)
|
||||
RF_SETUP = const(0x06)
|
||||
STATUS = const(0x07)
|
||||
OBSERVE_TX = const(0x08)
|
||||
RX_ADDR_P0 = const(0x0a)
|
||||
TX_ADDR = const(0x10)
|
||||
RX_PW_P0 = const(0x11)
|
||||
@@ -69,8 +69,10 @@ class NRF24L01:
|
||||
self.pipe0_read_addr = None
|
||||
pyb.delay(5)
|
||||
|
||||
# set address width to 5 bytes
|
||||
# set address width to 5 bytes and check for device present
|
||||
self.reg_write(SETUP_AW, 0b11)
|
||||
if self.reg_read(SETUP_AW) != 0b11:
|
||||
raise OSError("nRF24L01+ Hardware not responding")
|
||||
|
||||
# disable dynamic payloads
|
||||
self.reg_write(DYNPD, 0)
|
||||
@@ -80,7 +82,7 @@ class NRF24L01:
|
||||
self.reg_write(SETUP_RETR, (6 << 4) | 8)
|
||||
|
||||
# set rf power and speed
|
||||
self.set_power_speed(POWER_3, SPEED_1M)
|
||||
self.set_power_speed(POWER_3, SPEED_250K) # Best for point to point links
|
||||
|
||||
# init CRC
|
||||
self.set_crc(2)
|
||||
@@ -102,13 +104,6 @@ class NRF24L01:
|
||||
self.cs.high()
|
||||
return buf[0]
|
||||
|
||||
def reg_read_ret_status(self, reg):
|
||||
self.cs.low()
|
||||
status = self.spi.send_recv(reg)[0]
|
||||
buf = self.spi.recv(1)
|
||||
self.cs.high()
|
||||
return status
|
||||
|
||||
def reg_write(self, reg, buf):
|
||||
self.cs.low()
|
||||
status = self.spi.send_recv(0x20 | reg)[0]
|
||||
@@ -143,7 +138,7 @@ class NRF24L01:
|
||||
self.reg_write(CONFIG, config)
|
||||
|
||||
def set_channel(self, channel):
|
||||
self.reg_write(RF_CH, min(channel, 127))
|
||||
self.reg_write(RF_CH, min(channel, 125))
|
||||
|
||||
# address should be a bytes object 5 bytes long
|
||||
def open_tx_pipe(self, address):
|
||||
@@ -194,17 +189,26 @@ class NRF24L01:
|
||||
self.spi.send(R_RX_PAYLOAD)
|
||||
buf = self.spi.recv(self.payload_size)
|
||||
self.cs.high()
|
||||
|
||||
# clear RX ready flag
|
||||
self.reg_write(STATUS, RX_DR)
|
||||
|
||||
return buf
|
||||
|
||||
# blocking wait for tx complete
|
||||
def send(self, buf, timeout=500):
|
||||
send_nonblock = self.send_start(buf)
|
||||
start = pyb.millis()
|
||||
result = None
|
||||
while result is None and pyb.elapsed_millis(start) < timeout:
|
||||
result = self.send_done() # 1 == success, 2 == fail
|
||||
if result == 2:
|
||||
raise OSError("send failed")
|
||||
|
||||
# non-blocking tx
|
||||
def send_start(self, buf):
|
||||
# power up
|
||||
self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX)
|
||||
pyb.udelay(150)
|
||||
|
||||
# send the data
|
||||
self.cs.low()
|
||||
self.spi.send(W_TX_PAYLOAD)
|
||||
@@ -218,17 +222,12 @@ class NRF24L01:
|
||||
pyb.udelay(15) # needs to be >10us
|
||||
self.ce.low()
|
||||
|
||||
# blocking wait for tx complete
|
||||
start = pyb.millis()
|
||||
while pyb.millis() - start < timeout:
|
||||
status = self.reg_read_ret_status(OBSERVE_TX)
|
||||
if status & (TX_DS | MAX_RT):
|
||||
break
|
||||
# returns None if send still in progress, 1 for success, 2 for fail
|
||||
def send_done(self):
|
||||
if not (self.reg_read(STATUS) & (TX_DS | MAX_RT)):
|
||||
return None # tx not finished
|
||||
|
||||
# get and clear all status flags
|
||||
# either finished or failed: get and clear status flags, power down
|
||||
status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
|
||||
if not (status & TX_DS):
|
||||
raise OSError("send failed")
|
||||
|
||||
# power down
|
||||
self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP)
|
||||
return 1 if status & TX_DS else 2
|
||||
|
||||
202
drivers/sdcard/sdcard.py
Normal file
202
drivers/sdcard/sdcard.py
Normal file
@@ -0,0 +1,202 @@
|
||||
"""
|
||||
Micro Python driver for SD cards using SPI bus.
|
||||
|
||||
Requires an SPI bus and a CS pin. Provides readblocks and writeblocks
|
||||
methods so the device can be mounted as a filesystem.
|
||||
|
||||
Example usage:
|
||||
|
||||
import pyb, sdcard, os
|
||||
sd = sdcard.SDCard(pyb.SPI(1), pyb.Pin.board.X5)
|
||||
pyb.mount(sd, '/sd2')
|
||||
os.listdir('/')
|
||||
|
||||
"""
|
||||
|
||||
import pyb
|
||||
|
||||
class SDCard:
|
||||
CMD_TIMEOUT = const(100)
|
||||
|
||||
R1_IDLE_STATE = const(1 << 0)
|
||||
#R1_ERASE_RESET = const(1 << 1)
|
||||
R1_ILLEGAL_COMMAND = const(1 << 2)
|
||||
#R1_COM_CRC_ERROR = const(1 << 3)
|
||||
#R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
|
||||
#R1_ADDRESS_ERROR = const(1 << 5)
|
||||
#R1_PARAMETER_ERROR = const(1 << 6)
|
||||
|
||||
def __init__(self, spi, cs):
|
||||
self.spi = spi
|
||||
self.cs = cs
|
||||
|
||||
self.cmdbuf = bytearray(6)
|
||||
self.dummybuf = bytearray(512)
|
||||
for i in range(512):
|
||||
self.dummybuf[i] = 0xff
|
||||
self.dummybuf_memoryview = memoryview(self.dummybuf)
|
||||
|
||||
# initialise the card
|
||||
self.init_card()
|
||||
|
||||
def init_card(self):
|
||||
# init CS pin
|
||||
self.cs.high()
|
||||
self.cs.init(self.cs.OUT_PP)
|
||||
|
||||
# init SPI bus; use low data rate for initialisation
|
||||
self.spi.init(self.spi.MASTER, baudrate=100000, phase=0, polarity=0)
|
||||
|
||||
# clock card at least 100 cycles with cs high
|
||||
for i in range(16):
|
||||
self.spi.send(0xff)
|
||||
|
||||
# CMD0: init card; should return R1_IDLE_STATE (allow 2 attempts)
|
||||
if self.cmd(0, 0, 0x95) != R1_IDLE_STATE:
|
||||
if self.cmd(0, 0, 0x95) != R1_IDLE_STATE:
|
||||
raise OSError("no SD card")
|
||||
|
||||
# CMD8: determine card version
|
||||
r = self.cmd(8, 0x01aa, 0x87, 4)
|
||||
if r == R1_IDLE_STATE:
|
||||
self.init_card_v2()
|
||||
elif r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND):
|
||||
self.init_card_v1()
|
||||
else:
|
||||
raise OSError("couldn't determine SD card version")
|
||||
|
||||
# get the number of sectors
|
||||
# CMD9: response R2 (R1 byte + 16-byte block read)
|
||||
if self.cmd(9, 0, 0, 0, False) != 0:
|
||||
raise OSError("no response from SD card")
|
||||
csd = bytearray(16)
|
||||
self.readinto(csd)
|
||||
if csd[0] & 0xc0 != 0x40:
|
||||
raise OSError("SD card CSD format not supported")
|
||||
self.sectors = ((csd[8] << 8 | csd[9]) + 1) * 2014
|
||||
#print('sectors', self.sectors)
|
||||
|
||||
# CMD16: set block length to 512 bytes
|
||||
if self.cmd(16, 512, 0) != 0:
|
||||
raise OSError("can't set 512 block size")
|
||||
|
||||
# set to high data rate now that it's initialised
|
||||
self.spi.init(self.spi.MASTER, baudrate=1320000, phase=0, polarity=0)
|
||||
|
||||
def init_card_v1(self):
|
||||
for i in range(CMD_TIMEOUT):
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0, 0) == 0:
|
||||
self.cdv = 512
|
||||
#print("[SDCard] v1 card")
|
||||
return
|
||||
raise OSError("timeout waiting for v1 card")
|
||||
|
||||
def init_card_v2(self):
|
||||
for i in range(CMD_TIMEOUT):
|
||||
pyb.delay(50)
|
||||
self.cmd(58, 0, 0, 4)
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0x40000000, 0) == 0:
|
||||
self.cmd(58, 0, 0, 4)
|
||||
self.cdv = 1
|
||||
#print("[SDCard] v2 card")
|
||||
return
|
||||
raise OSError("timeout waiting for v2 card")
|
||||
|
||||
def cmd(self, cmd, arg, crc, final=0, release=True):
|
||||
self.cs.low()
|
||||
|
||||
# create and send the command
|
||||
buf = self.cmdbuf
|
||||
buf[0] = 0x40 | cmd
|
||||
buf[1] = arg >> 24
|
||||
buf[2] = arg >> 16
|
||||
buf[3] = arg >> 8
|
||||
buf[4] = arg
|
||||
buf[5] = crc
|
||||
self.spi.send(buf)
|
||||
|
||||
# wait for the repsonse (response[7] == 0)
|
||||
for i in range(CMD_TIMEOUT):
|
||||
response = self.spi.send_recv(0xff)[0]
|
||||
if not (response & 0x80):
|
||||
# this could be a big-endian integer that we are getting here
|
||||
for j in range(final):
|
||||
self.spi.send(0xff)
|
||||
if release:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
return response
|
||||
|
||||
# timeout
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
return -1
|
||||
|
||||
def readinto(self, buf):
|
||||
self.cs.low()
|
||||
|
||||
# read until start byte (0xff)
|
||||
while self.spi.send_recv(0xff)[0] != 0xfe:
|
||||
pass
|
||||
|
||||
# read data
|
||||
mv = self.dummybuf_memoryview[:len(buf)]
|
||||
self.spi.send_recv(mv, recv=buf)
|
||||
|
||||
# read checksum
|
||||
self.spi.send(0xff)
|
||||
self.spi.send(0xff)
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
|
||||
def write(self, buf):
|
||||
self.cs.low()
|
||||
|
||||
# send: start of block, data, checksum
|
||||
self.spi.send(0xfe)
|
||||
self.spi.send(buf)
|
||||
self.spi.send(0xff)
|
||||
self.spi.send(0xff)
|
||||
|
||||
# check the response
|
||||
if (self.spi.send_recv(0xff)[0] & 0x1f) != 0x05:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
return
|
||||
|
||||
# wait for write to finish
|
||||
while self.spi.send_recv(0xff)[0] == 0:
|
||||
pass
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
|
||||
def count(self):
|
||||
return self.sectors
|
||||
|
||||
def readblocks(self, block_num, buf):
|
||||
# TODO support multiple block reads
|
||||
assert len(buf) == 512
|
||||
|
||||
# CMD17: set read address for single block
|
||||
if self.cmd(17, block_num * self.cdv, 0) != 0:
|
||||
return 1
|
||||
|
||||
# receive the data
|
||||
self.readinto(buf)
|
||||
return 0
|
||||
|
||||
def writeblocks(self, block_num, buf):
|
||||
# TODO support multiple block writes
|
||||
assert len(buf) == 512
|
||||
|
||||
# CMD24: set write address for single block
|
||||
if self.cmd(24, block_num * self.cdv, 0) != 0:
|
||||
return 1
|
||||
|
||||
# send the data
|
||||
self.write(buf)
|
||||
return 0
|
||||
@@ -49,6 +49,9 @@
|
||||
//! THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "socket.h"
|
||||
|
||||
extern void HAL_Delay(uint32_t);
|
||||
@@ -85,7 +88,19 @@ static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
|
||||
if(len == 0) return SOCKERR_DATALEN; \
|
||||
}while(0); \
|
||||
|
||||
void WIZCHIP_EXPORT(socket_reset)(void) {
|
||||
sock_any_port = SOCK_ANY_PORT_NUM;
|
||||
sock_io_mode = 0;
|
||||
sock_is_sending = 0;
|
||||
/*
|
||||
memset(sock_remained_size, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t));
|
||||
memset(sock_pack_info, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint8_t));
|
||||
*/
|
||||
|
||||
#if _WIZCHIP_ == 5200
|
||||
memset(sock_next_rd, 0, _WIZCHIP_SOCK_NUM_ * sizeof(uint16_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
|
||||
{
|
||||
@@ -336,8 +351,13 @@ int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len)
|
||||
if(recvsize != 0) break;
|
||||
else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
|
||||
{
|
||||
// dpgeorge: Getting here seems to be an orderly shutdown of the
|
||||
// socket, and trying to get POSIX behaviour we return 0 because:
|
||||
// "If no messages are available to be received and the peer has per‐
|
||||
// formed an orderly shutdown, recv() shall return 0".
|
||||
// TODO this return value clashes with SOCK_BUSY in non-blocking mode.
|
||||
WIZCHIP_EXPORT(close)(sn);
|
||||
return SOCKERR_SOCKSTATUS;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -133,6 +133,9 @@
|
||||
#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received.
|
||||
#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet.
|
||||
|
||||
// resets all global state associated with the socket interface
|
||||
void WIZCHIP_EXPORT(socket_reset)(void);
|
||||
|
||||
/**
|
||||
* @ingroup WIZnet_socket_APIs
|
||||
* @brief Open a socket.
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
//
|
||||
|
||||
#include "wizchip_conf.h"
|
||||
#include "socket.h"
|
||||
|
||||
/**
|
||||
* @brief Default function to enable interrupt.
|
||||
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
|
||||
@@ -328,6 +330,9 @@ int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize)
|
||||
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
|
||||
setSn_RXBUF_SIZE(i, rxsize[i]);
|
||||
}
|
||||
|
||||
WIZCHIP_EXPORT(socket_reset)();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,12 @@ include ../py/py.mk
|
||||
|
||||
PORT = /dev/ttyACM0
|
||||
CROSS_COMPILE = xtensa-lx106-elf-
|
||||
ESP_SDK = $(shell $(CC) -print-sysroot)/..
|
||||
ESP_SDK = $(shell $(CC) -print-sysroot)/usr
|
||||
|
||||
INC = -I.
|
||||
INC += -I$(PY_SRC)
|
||||
INC += -I..
|
||||
INC += -I../stmhal
|
||||
INC += -I../lib/mp-readline
|
||||
INC += -I$(BUILD)
|
||||
INC += -I$(ESP_SDK)/include
|
||||
|
||||
@@ -52,7 +53,10 @@ STM_SRC_C = $(addprefix stmhal/,\
|
||||
printf.c \
|
||||
string0.c \
|
||||
pyexec.c \
|
||||
readline.c \
|
||||
)
|
||||
|
||||
LIB_SRC_C = $(addprefix lib/,\
|
||||
mp-readline/readline.c \
|
||||
)
|
||||
|
||||
SRC_S = \
|
||||
@@ -63,6 +67,7 @@ OBJ += $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
|
||||
#OBJ += $(BUILD)/pins_$(BOARD).o
|
||||
|
||||
all: $(BUILD)/firmware-combined.bin
|
||||
|
||||
51
esp8266/README.md
Normal file
51
esp8266/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
Micro Python port to ESP8266
|
||||
============================
|
||||
|
||||
This is a port of Micro Python to the Espressif ESP8266 wifi module.
|
||||
|
||||
Currently implemented features include:
|
||||
- REPL (Python prompt) over UART0.
|
||||
- 24k heap RAM available for Python code.
|
||||
- Garbage collector, exceptions.
|
||||
- Unicode support.
|
||||
- Builtin modules: gc, array, collections, io, struct, sys.
|
||||
- C long-long type used as bignum implementation (gives 64 signed ints).
|
||||
|
||||
Note that floating-point numbers are not supported.
|
||||
|
||||
On the TODO list:
|
||||
- Wifi support.
|
||||
- GPIO support.
|
||||
- Internal filesystem using the flash.
|
||||
- ...
|
||||
|
||||
Build instructions
|
||||
------------------
|
||||
|
||||
The tool chain required for the build is the OpenSource ESP SDK, which can be
|
||||
found at <https://github.com/pfalcon/esp-open-sdk>. Clone this repository and
|
||||
run `make` in its directory to build and install the SDK locally.
|
||||
|
||||
Then, to build Micro Python for the ESP8266, just run:
|
||||
```bash
|
||||
$ make
|
||||
```
|
||||
This should produce binary images in the `build/` subdirectory. To flash them
|
||||
to your ESP8266, use:
|
||||
```bash
|
||||
$ make deploy
|
||||
```
|
||||
This will use the `esptool.py` script to download the images. You must have
|
||||
your ESP module in the bootloader, and connected to a serial port on your PC.
|
||||
The default serial port is `/dev/ttyACM0`. To specify another, use, eg:
|
||||
```bash
|
||||
$ make PORT=/dev/ttyUSB0 deploy
|
||||
```
|
||||
|
||||
The images that are built are:
|
||||
- `firmware.elf-0x00000.bin`: to be flashed at 0x00000
|
||||
- `firmware.elf-0x10000.bin`: to be flashed at 0x10000
|
||||
|
||||
There is also a combined image, made up of the above 2 binary files with the
|
||||
appropriate padding:
|
||||
- `firmware-combined.bin`: to be flashed at 0x00000
|
||||
@@ -73,9 +73,23 @@ SECTIONS
|
||||
{
|
||||
_irom0_text_start = ABSOLUTE(.);
|
||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||
*py*.o*(.literal* .text*)
|
||||
*gccollect.o*(.literal* .text*)
|
||||
*gchelper.o*(.literal* .text*)
|
||||
|
||||
/* we put some specific text in this section */
|
||||
*py/*.o*(.literal* .text*)
|
||||
*pyexec.o(.literal*, .text*)
|
||||
*readline.o(.literal*, .text*)
|
||||
*pybstdio.o(.literal*, .text*)
|
||||
*modpyb.o(.literal*, .text*)
|
||||
*gccollect.o(.literal* .text*)
|
||||
*gchelper.o(.literal* .text*)
|
||||
|
||||
/* we put as much rodata as possible in this section */
|
||||
/* note that only rodata accessed as a machine word is allowed here */
|
||||
*py/qstr.o(.rodata.const_pool)
|
||||
*py/*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
|
||||
*py/*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
|
||||
*py/*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
|
||||
|
||||
_irom0_text_end = ABSOLUTE(.);
|
||||
} >irom0_0_seg :irom0_0_phdr
|
||||
|
||||
@@ -90,13 +104,6 @@ SECTIONS
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
*qstr.o(.rodata.const_pool)
|
||||
*.o(.rodata.mp_type_*)
|
||||
/*
|
||||
can't put these here for some reason...
|
||||
*builtin.o(.rodata.mp_builtin_*_obj)
|
||||
*parse.o(.rodata.rule_*)
|
||||
*/
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
@@ -40,4 +40,7 @@ void HAL_Delay(uint32_t Delay);
|
||||
void mp_hal_set_interrupt_char(int c);
|
||||
uint32_t mp_hal_get_cpu_freq(void);
|
||||
|
||||
#define UART_TASK_ID 0
|
||||
void uart_task_init();
|
||||
|
||||
#endif // _INCLUDED_MPHAL_H_
|
||||
|
||||
@@ -25,13 +25,8 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "gc.h"
|
||||
#include "py/gc.h"
|
||||
#include "gccollect.h"
|
||||
|
||||
STATIC uint32_t stack_end;
|
||||
|
||||
@@ -27,27 +27,24 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "parsehelper.h"
|
||||
#include "compile.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
#include "gc.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/parsehelper.h"
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/gc.h"
|
||||
#include "pyexec.h"
|
||||
#include "gccollect.h"
|
||||
#include MICROPY_HAL_H
|
||||
|
||||
STATIC char heap[16384];
|
||||
|
||||
void user_init(void) {
|
||||
soft_reset:
|
||||
//mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024);
|
||||
mp_stack_set_limit(10240);
|
||||
mp_hal_init();
|
||||
gc_init(&_heap_start, &_heap_end);
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
gc_collect_init();
|
||||
mp_init();
|
||||
mp_obj_list_init(mp_sys_path, 0);
|
||||
@@ -55,6 +52,12 @@ soft_reset:
|
||||
|
||||
printf("\n");
|
||||
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
pyexec_friendly_repl_init();
|
||||
uart_task_init();
|
||||
return;
|
||||
goto soft_reset;
|
||||
#else
|
||||
for (;;) {
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
if (pyexec_raw_repl() != 0) {
|
||||
@@ -68,6 +71,7 @@ soft_reset:
|
||||
}
|
||||
|
||||
goto soft_reset;
|
||||
#endif
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
|
||||
@@ -24,19 +24,16 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "gc.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "pyexec.h"
|
||||
#include "pybstdio.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "user_interface.h"
|
||||
|
||||
STATIC mp_obj_t pyb_info(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// print info about memory
|
||||
@@ -140,6 +137,12 @@ STATIC mp_obj_t pyb_udelay(mp_obj_t usec_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay);
|
||||
|
||||
STATIC mp_obj_t pyb_hard_reset(void) {
|
||||
system_restart();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_hard_reset_obj, pyb_hard_reset);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
|
||||
|
||||
@@ -153,18 +156,10 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hard_reset), (mp_obj_t)&pyb_hard_reset_obj },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t pyb_module_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = MP_ARRAY_SIZE(pyb_module_globals_table),
|
||||
.alloc = MP_ARRAY_SIZE(pyb_module_globals_table),
|
||||
.table = (mp_map_elem_t*)pyb_module_globals_table,
|
||||
},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);
|
||||
|
||||
const mp_obj_module_t pyb_module = {
|
||||
.base = { &mp_type_module },
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_STACK_CHECK (0)
|
||||
#define MICROPY_REPL_EVENT_DRIVEN (1)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||
@@ -61,6 +63,11 @@ extern const struct _mp_obj_module_t pyb_module;
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
const char *readline_hist[8];
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#include <alloca.h>
|
||||
|
||||
|
||||
@@ -25,16 +25,11 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "misc.h"
|
||||
#include "obj.h"
|
||||
#include "stream.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/stream.h"
|
||||
#include "pybstdio.h"
|
||||
#include MICROPY_HAL_H
|
||||
|
||||
|
||||
@@ -39,3 +39,4 @@ Q(elapsed_micros)
|
||||
Q(delay)
|
||||
Q(udelay)
|
||||
Q(sync)
|
||||
Q(hard_reset)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "uart_register.h"
|
||||
#include "etshal.h"
|
||||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "esp_mphal.h"
|
||||
|
||||
#define RX_BUF_SIZE (256)
|
||||
|
||||
@@ -27,6 +29,8 @@ static uint16_t rx_buf_in;
|
||||
static uint16_t rx_buf_out;
|
||||
static uint8_t rx_buf[RX_BUF_SIZE];
|
||||
|
||||
static os_event_t uart_evt_queue[16];
|
||||
|
||||
static void uart0_rx_intr_handler(void *para);
|
||||
|
||||
/******************************************************************************
|
||||
@@ -148,11 +152,15 @@ static void uart0_rx_intr_handler(void *para) {
|
||||
read_chars:
|
||||
while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
|
||||
RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
|
||||
#if 1 //MICROPY_REPL_EVENT_DRIVEN is not available here
|
||||
system_os_post(UART_TASK_ID, 0, RcvChar);
|
||||
#else
|
||||
uint16_t rx_buf_in_next = (rx_buf_in + 1) % RX_BUF_SIZE;
|
||||
if (rx_buf_in_next != rx_buf_out) {
|
||||
rx_buf[rx_buf_in] = RcvChar;
|
||||
rx_buf_in = rx_buf_in_next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,3 +197,15 @@ void ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br) {
|
||||
void ICACHE_FLASH_ATTR uart_reattach() {
|
||||
uart_init(UART_BIT_RATE_74880, UART_BIT_RATE_74880);
|
||||
}
|
||||
|
||||
// Task-based UART interface
|
||||
|
||||
int pyexec_friendly_repl_process_char(int c);
|
||||
|
||||
void uart_task_handler(os_event_t *evt) {
|
||||
pyexec_friendly_repl_process_char(evt->par);
|
||||
}
|
||||
|
||||
void uart_task_init() {
|
||||
system_os_task(uart_task_handler, UART_TASK_ID, uart_evt_queue, sizeof(uart_evt_queue) / sizeof(*uart_evt_queue));
|
||||
}
|
||||
|
||||
77
extmod/modubinascii.c
Normal file
77
extmod/modubinascii.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
|
||||
#if MICROPY_PY_UBINASCII
|
||||
|
||||
STATIC mp_obj_t mod_binascii_hexlify(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, bufinfo.len * 2);
|
||||
byte *in = bufinfo.buf, *out = (byte*)vstr.buf;
|
||||
for (mp_uint_t i = bufinfo.len; i--;) {
|
||||
byte d = (*in >> 4);
|
||||
if (d > 9) {
|
||||
d += 'a' - '9' - 1;
|
||||
}
|
||||
*out++ = d + '0';
|
||||
d = (*in++ & 0xf);
|
||||
if (d > 9) {
|
||||
d += 'a' - '9' - 1;
|
||||
}
|
||||
*out++ = d + '0';
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_hexlify_obj, 1, 2, mod_binascii_hexlify);
|
||||
|
||||
STATIC const mp_map_elem_t mp_module_binascii_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ubinascii) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hexlify), (mp_obj_t)&mod_binascii_hexlify_obj },
|
||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_unhexlify), (mp_obj_t)&mod_binascii_unhexlify_obj },
|
||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_a2b_base64), (mp_obj_t)&mod_binascii_a2b_base64_obj },
|
||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_b2a_base64), (mp_obj_t)&mod_binascii_b2a_base64_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ubinascii = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_ubinascii,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_binascii_globals,
|
||||
};
|
||||
|
||||
#endif //MICROPY_PY_UBINASCII
|
||||
@@ -27,14 +27,11 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "objtuple.h"
|
||||
#include "binary.h"
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/binary.h"
|
||||
|
||||
#if MICROPY_PY_UCTYPES
|
||||
|
||||
@@ -120,11 +117,12 @@ typedef struct _mp_obj_uctypes_struct_t {
|
||||
uint32_t flags;
|
||||
} mp_obj_uctypes_struct_t;
|
||||
|
||||
STATIC NORETURN void syntax_error() {
|
||||
STATIC NORETURN void syntax_error(void) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "syntax error in uctypes descriptor"));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t uctypes_struct_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
(void)n_kw;
|
||||
if (n_args < 2 || n_args > 3) {
|
||||
syntax_error();
|
||||
}
|
||||
@@ -140,6 +138,7 @@ STATIC mp_obj_t uctypes_struct_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_u
|
||||
}
|
||||
|
||||
STATIC void uctypes_struct_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_uctypes_struct_t *self = self_in;
|
||||
const char *typen = "unk";
|
||||
if (MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)) {
|
||||
@@ -559,7 +558,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
|
||||
/// \function addressof()
|
||||
/// Return address of object's data (applies to object providing buffer
|
||||
/// interface).
|
||||
mp_obj_t uctypes_struct_addressof(mp_obj_t buf) {
|
||||
STATIC mp_obj_t uctypes_struct_addressof(mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
return mp_obj_new_int((mp_int_t)bufinfo.buf);
|
||||
@@ -570,8 +569,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(uctypes_struct_addressof_obj, uctypes_struct_addressof
|
||||
/// Capture memory at given address of given size as bytearray. Memory is
|
||||
/// captured by reference (and thus memory pointed by bytearray may change
|
||||
/// or become invalid at later time). Use bytes_at() to capture by value.
|
||||
mp_obj_t uctypes_struct_bytearray_at(mp_obj_t ptr, mp_obj_t size) {
|
||||
return mp_obj_new_bytearray_by_ref(mp_obj_int_get(size), (void*)mp_obj_int_get(ptr));
|
||||
STATIC mp_obj_t uctypes_struct_bytearray_at(mp_obj_t ptr, mp_obj_t size) {
|
||||
return mp_obj_new_bytearray_by_ref(mp_obj_int_get_truncated(size), (void*)mp_obj_int_get_truncated(ptr));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytearray_at_obj, uctypes_struct_bytearray_at);
|
||||
|
||||
@@ -579,8 +578,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytearray_at_obj, uctypes_struct_bytear
|
||||
/// Capture memory at given address of given size as bytes. Memory is
|
||||
/// captured by value, i.e. copied. Use bytearray_at() to capture by reference
|
||||
/// ("zero copy").
|
||||
mp_obj_t uctypes_struct_bytes_at(mp_obj_t ptr, mp_obj_t size) {
|
||||
return mp_obj_new_bytes((void*)mp_obj_int_get(ptr), mp_obj_int_get(size));
|
||||
STATIC mp_obj_t uctypes_struct_bytes_at(mp_obj_t ptr, mp_obj_t size) {
|
||||
return mp_obj_new_bytes((void*)mp_obj_int_get_truncated(ptr), mp_obj_int_get_truncated(size));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytes_at_obj, uctypes_struct_bytes_at);
|
||||
|
||||
@@ -649,16 +648,7 @@ STATIC const mp_map_elem_t mp_module_uctypes_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ARRAY), MP_OBJ_NEW_SMALL_INT(TYPE2SMALLINT(ARRAY, AGG_TYPE_BITS)) },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t mp_module_uctypes_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = MP_ARRAY_SIZE(mp_module_uctypes_globals_table),
|
||||
.alloc = MP_ARRAY_SIZE(mp_module_uctypes_globals_table),
|
||||
.table = (mp_map_elem_t*)mp_module_uctypes_globals_table,
|
||||
},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_uctypes_globals, mp_module_uctypes_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_uctypes = {
|
||||
.base = { &mp_type_module },
|
||||
|
||||
@@ -27,12 +27,8 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_UHASHLIB
|
||||
|
||||
@@ -67,14 +63,15 @@ MP_DEFINE_CONST_FUN_OBJ_2(hash_update_obj, hash_update);
|
||||
|
||||
STATIC mp_obj_t hash_digest(mp_obj_t self_in) {
|
||||
mp_obj_hash_t *self = self_in;
|
||||
byte *hash;
|
||||
mp_obj_t o = mp_obj_str_builder_start(&mp_type_bytes, SHA256_BLOCK_SIZE, &hash);
|
||||
sha256_final((SHA256_CTX*)self->state, hash);
|
||||
return mp_obj_str_builder_end(o);
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, SHA256_BLOCK_SIZE);
|
||||
sha256_final((SHA256_CTX*)self->state, (byte*)vstr.buf);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(hash_digest_obj, hash_digest);
|
||||
|
||||
STATIC mp_obj_t hash_hexdigest(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
mp_not_implemented("");
|
||||
#if 0
|
||||
mp_obj_hash_t *self = self_in;
|
||||
@@ -105,16 +102,7 @@ STATIC const mp_map_elem_t mp_module_hashlib_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sha256), (mp_obj_t)&sha256_type },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t mp_module_hashlib_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = MP_ARRAY_SIZE(mp_module_hashlib_globals_table),
|
||||
.alloc = MP_ARRAY_SIZE(mp_module_hashlib_globals_table),
|
||||
.table = (mp_map_elem_t*)mp_module_hashlib_globals_table,
|
||||
},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_hashlib_globals, mp_module_hashlib_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_uhashlib = {
|
||||
.base = { &mp_type_module },
|
||||
|
||||
@@ -26,14 +26,10 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objlist.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_UHEAPQ
|
||||
|
||||
@@ -118,16 +114,7 @@ STATIC const mp_map_elem_t mp_module_uheapq_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_heapify), (mp_obj_t)&mod_uheapq_heapify_obj },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t mp_module_uheapq_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = MP_ARRAY_SIZE(mp_module_uheapq_globals_table),
|
||||
.alloc = MP_ARRAY_SIZE(mp_module_uheapq_globals_table),
|
||||
.table = (mp_map_elem_t*)mp_module_uheapq_globals_table,
|
||||
},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_uheapq_globals, mp_module_uheapq_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_uheapq = {
|
||||
.base = { &mp_type_module },
|
||||
|
||||
@@ -28,14 +28,10 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objlist.h"
|
||||
#include "parsenum.h"
|
||||
#include "runtime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/parsenum.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_UJSON
|
||||
|
||||
@@ -85,6 +81,9 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
|
||||
case ',':
|
||||
case ':':
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
s += 1;
|
||||
goto cont;
|
||||
case 'n':
|
||||
@@ -259,16 +258,7 @@ STATIC const mp_map_elem_t mp_module_ujson_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_loads), (mp_obj_t)&mod_ujson_loads_obj },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t mp_module_ujson_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = MP_ARRAY_SIZE(mp_module_ujson_globals_table),
|
||||
.alloc = MP_ARRAY_SIZE(mp_module_ujson_globals_table),
|
||||
.table = (mp_map_elem_t*)mp_module_ujson_globals_table,
|
||||
},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_ujson_globals, mp_module_ujson_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ujson = {
|
||||
.base = { &mp_type_module },
|
||||
|
||||
@@ -28,13 +28,9 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "binary.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
|
||||
#if MICROPY_PY_URE
|
||||
|
||||
@@ -56,13 +52,14 @@ typedef struct _mp_obj_match_t {
|
||||
|
||||
|
||||
STATIC void match_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_match_t *self = self_in;
|
||||
print(env, "<match num=%d @%p>", self->num_matches);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t match_group(mp_obj_t self_in, mp_obj_t no_in) {
|
||||
mp_obj_match_t *self = self_in;
|
||||
mp_int_t no = mp_obj_int_get(no_in);
|
||||
mp_int_t no = mp_obj_int_get_truncated(no_in);
|
||||
if (no < 0 || no >= self->num_matches / 2) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_IndexError, no_in));
|
||||
}
|
||||
@@ -86,11 +83,13 @@ STATIC const mp_obj_type_t match_type = {
|
||||
};
|
||||
|
||||
STATIC void re_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_re_t *self = self_in;
|
||||
print(env, "<re %p>", self);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
mp_obj_re_t *self = args[0];
|
||||
Subject subj;
|
||||
mp_uint_t len;
|
||||
@@ -130,7 +129,7 @@ STATIC mp_obj_t re_split(uint n_args, const mp_obj_t *args) {
|
||||
|
||||
int maxsplit = 0;
|
||||
if (n_args > 2) {
|
||||
maxsplit = mp_obj_int_get(args[2]);
|
||||
maxsplit = mp_obj_int_get_truncated(args[2]);
|
||||
}
|
||||
|
||||
mp_obj_t retval = mp_obj_new_list(0, NULL);
|
||||
@@ -175,7 +174,7 @@ STATIC const mp_obj_type_t re_type = {
|
||||
.locals_dict = (mp_obj_t)&re_locals_dict,
|
||||
};
|
||||
|
||||
mp_obj_t mod_re_compile(uint n_args, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t mod_re_compile(uint n_args, const mp_obj_t *args) {
|
||||
const char *re_str = mp_obj_str_get_str(args[0]);
|
||||
int size = re1_5_sizecode(re_str);
|
||||
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
|
||||
@@ -196,6 +195,7 @@ mp_obj_t mod_re_compile(uint n_args, const mp_obj_t *args) {
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile);
|
||||
|
||||
STATIC mp_obj_t mod_re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
mp_obj_re_t *self = mod_re_compile(1, args);
|
||||
|
||||
const mp_obj_t args2[] = {self, args[1]};
|
||||
@@ -221,16 +221,7 @@ STATIC const mp_map_elem_t mp_module_re_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_DEBUG), MP_OBJ_NEW_SMALL_INT(FLAG_DEBUG) },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t mp_module_re_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = MP_ARRAY_SIZE(mp_module_re_globals_table),
|
||||
.alloc = MP_ARRAY_SIZE(mp_module_re_globals_table),
|
||||
.table = (mp_map_elem_t*)mp_module_re_globals_table,
|
||||
},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ure = {
|
||||
.base = { &mp_type_module },
|
||||
|
||||
@@ -31,12 +31,8 @@
|
||||
#include <sys/time.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "nlr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_UZLIB
|
||||
|
||||
@@ -59,6 +55,7 @@ STATIC int mod_uzlib_grow_buf(TINF_DATA *d, unsigned alloc_req) {
|
||||
}
|
||||
|
||||
STATIC mp_obj_t mod_uzlib_decompress(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
mp_obj_t data = args[0];
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
||||
@@ -87,16 +84,7 @@ STATIC const mp_map_elem_t mp_module_uzlib_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_decompress), (mp_obj_t)&mod_uzlib_decompress_obj },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t mp_module_uzlib_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = MP_ARRAY_SIZE(mp_module_uzlib_globals_table),
|
||||
.alloc = MP_ARRAY_SIZE(mp_module_uzlib_globals_table),
|
||||
.table = (mp_map_elem_t*)mp_module_uzlib_globals_table,
|
||||
},
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_uzlib_globals, mp_module_uzlib_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_uzlib = {
|
||||
.base = { &mp_type_module },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FatFs Module Source Files R0.10 (C)ChaN, 2013
|
||||
FatFs Module Source Files R0.10c (C)ChaN, 2014
|
||||
|
||||
|
||||
FILES
|
||||
@@ -24,7 +24,7 @@ AGREEMENTS
|
||||
small embedded systems. This is a free software and is opened for education,
|
||||
research and commercial developments under license policy of following trems.
|
||||
|
||||
Copyright (C) 2013, ChaN, all right reserved.
|
||||
Copyright (C) 2014, ChaN, all right reserved.
|
||||
|
||||
* The FatFs module is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
@@ -134,7 +134,7 @@ REVISION HISTORY
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
|
||||
Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL == 1)
|
||||
Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL)
|
||||
|
||||
Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
@@ -145,3 +145,19 @@ REVISION HISTORY
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
|
||||
|
||||
Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1.
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired.
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions.
|
||||
|
||||
Mar 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN.
|
||||
|
||||
Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel().
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry.
|
||||
230
lib/fatfs/diskio.c
Normal file
230
lib/fatfs/diskio.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control modules to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "usbdisk.h" /* Example: USB drive control */
|
||||
#include "atadrive.h" /* Example: ATA drive control */
|
||||
#include "sdcard.h" /* Example: MMC/SDC contorl */
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define ATA 0 /* Example: Map ATA drive to drive number 0 */
|
||||
#define MMC 1 /* Example: Map MMC/SD card to drive number 1 */
|
||||
#define USB 2 /* Example: Map USB drive to drive number 2 */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case ATA :
|
||||
result = ATA_disk_status();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case MMC :
|
||||
result = MMC_disk_status();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case USB :
|
||||
result = USB_disk_status();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
}
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case ATA :
|
||||
result = ATA_disk_initialize();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case MMC :
|
||||
result = MMC_disk_initialize();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case USB :
|
||||
result = USB_disk_initialize();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
}
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case ATA :
|
||||
// translate the arguments here
|
||||
|
||||
result = ATA_disk_read(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case MMC :
|
||||
// translate the arguments here
|
||||
|
||||
result = MMC_disk_read(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case USB :
|
||||
// translate the arguments here
|
||||
|
||||
result = USB_disk_read(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case ATA :
|
||||
// translate the arguments here
|
||||
|
||||
result = ATA_disk_write(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case MMC :
|
||||
// translate the arguments here
|
||||
|
||||
result = MMC_disk_write(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case USB :
|
||||
// translate the arguments here
|
||||
|
||||
result = USB_disk_write(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case ATA :
|
||||
|
||||
// Process of the command for the ATA drive
|
||||
|
||||
return res;
|
||||
|
||||
case MMC :
|
||||
|
||||
// Process of the command for the MMC/SD card
|
||||
|
||||
return res;
|
||||
|
||||
case USB :
|
||||
|
||||
// Process of the command the USB drive
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2013
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
@@ -34,12 +34,13 @@ typedef enum {
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE*buff, DWORD sector, BYTE count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, BYTE count);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
@@ -47,14 +48,14 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
|
||||
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (not used by FatFs) */
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
@@ -72,18 +73,8 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
|
||||
/* MMC card type flags (MMC_GET_TYPE) */
|
||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
||||
#define CT_SD1 0x02 /* SD ver 1 */
|
||||
#define CT_SD2 0x04 /* SD ver 2 */
|
||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
||||
#define CT_BLOCK 0x08 /* Block addressing */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.10 (C)ChaN, 2013
|
||||
/ FatFs - FAT file system module include file R0.10c (C)ChaN, 2014
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following terms.
|
||||
/
|
||||
/ Copyright (C) 2013, ChaN, all right reserved.
|
||||
/ Copyright (C) 2014, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
@@ -15,7 +15,7 @@
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 80960 /* Revision ID */
|
||||
#define _FATFS 80376 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -23,7 +23,6 @@ extern "C" {
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
@@ -53,7 +52,7 @@ extern const PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
@@ -75,10 +74,6 @@ typedef char TCHAR;
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
union{
|
||||
UINT d32[_MAX_SS/4]; /* Force 32bits alignement */
|
||||
BYTE d8[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
}win;
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
@@ -87,7 +82,7 @@ typedef struct {
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
#if _MAX_SS != _MIN_SS
|
||||
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
@@ -100,14 +95,14 @@ typedef struct {
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD volbase; /* Volume start sector */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
@@ -115,30 +110,27 @@ typedef struct {
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
#if !_FS_TINY
|
||||
union{
|
||||
UINT d32[_MAX_SS/4]; /* Force 32bits alignement */
|
||||
BYTE d8[_MAX_SS]; /* File data read/write buffer */
|
||||
}buf;
|
||||
#endif
|
||||
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE flag; /* Status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File data start cluster (0:no data cluster, always 0 when fsize is 0) */
|
||||
DWORD clust; /* Current cluster of fpter */
|
||||
DWORD dsect; /* Current data sector of fpter */
|
||||
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
|
||||
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
|
||||
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the window */
|
||||
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
|
||||
#endif
|
||||
#if _FS_LOCK
|
||||
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
@@ -147,12 +139,6 @@ typedef struct {
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
#if !_FS_TINY
|
||||
union{
|
||||
UINT d32[_MAX_SS/4]; /* Force 32bits alignement */
|
||||
BYTE d8[_MAX_SS]; /* File data read/write buffer */
|
||||
}buf;
|
||||
#endif
|
||||
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
WORD index; /* Current read/write index number */
|
||||
@@ -239,7 +225,7 @@ FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* sn); /* Get volume label */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */
|
||||
@@ -249,7 +235,7 @@ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
@@ -265,7 +251,7 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
#if !_FS_READONLY && !_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
@@ -287,10 +273,16 @@ void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
// dpgeorge: added the following 3 declarations to support our volume names
|
||||
|
||||
/* Returns logical drive number (-1:invalid drive) */
|
||||
// Current drive
|
||||
extern BYTE ff_CurrVol;
|
||||
|
||||
// Returns logical drive number (-1:invalid drive)
|
||||
int ff_get_ldnumber(const TCHAR** path);
|
||||
|
||||
// Store the volume name into dest, and advance the pointer
|
||||
void ff_get_volname(BYTE vol, TCHAR **dest);
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
@@ -355,4 +347,3 @@ int ff_get_ldnumber(const TCHAR** path);
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
|
||||
270
lib/fatfs/ffconf_template.h
Normal file
270
lib/fatfs/ffconf_template.h
Normal file
@@ -0,0 +1,270 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FFCONF 80376 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
|
||||
/ bytes. Instead of private sector buffer eliminated from the file object,
|
||||
/ common sector buffer in the file system object (FATFS) is used for the file
|
||||
/ data transfer. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes basic writing API functions, f_write(),
|
||||
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
|
||||
/ f_getfree() and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
|
||||
/ f_truncate() and f_rename() function are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_READONLY need to be set to 0. */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
/* To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
|
||||
|
||||
|
||||
#define _USE_LFN 0
|
||||
#define _MAX_LFN 255
|
||||
/* The _USE_LFN option switches the LFN feature.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ When enable the LFN feature, Unicode handling functions (option/unicode.c) must
|
||||
/ be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree(), must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0
|
||||
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
|
||||
/ To use Unicode string for the path name, enable LFN feature and set _LFN_UNICODE
|
||||
/ to 1. This option also affects behavior of string I/O functions. */
|
||||
|
||||
|
||||
#define _STRF_ENCODE 3
|
||||
/* When _LFN_UNICODE is 1, this option selects the character encoding on the file to
|
||||
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
|
||||
/
|
||||
/ 0: ANSI/OEM
|
||||
/ 1: UTF-16LE
|
||||
/ 2: UTF-16BE
|
||||
/ 3: UTF-8
|
||||
/
|
||||
/ When _LFN_UNICODE is 0, this option has no effect. */
|
||||
|
||||
|
||||
#define _FS_RPATH 0
|
||||
/* This option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path feature. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
/
|
||||
/ Note that directory items read via f_readdir() are affected by this option. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
/* _STR_VOLUME_ID option switches string volume ID feature.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0
|
||||
/* This option switches multi-partition feature. By default (0), each logical drive
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
#define _MAX_SS 512
|
||||
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
|
||||
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _USE_TRIM 0
|
||||
/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable)
|
||||
/ To enable Trim feature, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 11
|
||||
#define _NORTC_MDAY 9
|
||||
#define _NORTC_YEAR 2014
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
|
||||
/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
|
||||
/ to be added to the project to read current time form RTC. _NORTC_MON,
|
||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (_FS_READONLY == 1). */
|
||||
|
||||
|
||||
#define _FS_LOCK 0
|
||||
/* The _FS_LOCK option switches file lock feature to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock feature. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock feature. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock feature is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define _FS_REENTRANT 0
|
||||
#define _FS_TIMEOUT 1000
|
||||
#define _SYNC_t HANDLE
|
||||
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this feature.
|
||||
/
|
||||
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc.. */
|
||||
|
||||
|
||||
#define _WORD_ACCESS 0
|
||||
/* The _WORD_ACCESS option is an only platform dependent option. It defines
|
||||
/ which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||
/ 1: Word access. Do not choose this unless under both the following conditions.
|
||||
/
|
||||
/ * Address misaligned memory access is always allowed to ALL instructions.
|
||||
/ * Byte order on the memory is little-endian.
|
||||
/
|
||||
/ If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
|
||||
/ Following table shows allowable settings of some processor types.
|
||||
/
|
||||
/ ARM7TDMI 0 ColdFire 0 V850E 0
|
||||
/ Cortex-M3 0 Z80 0/1 V850ES 0/1
|
||||
/ Cortex-M0 0 x86 0/1 TLCS-870 0/1
|
||||
/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1
|
||||
/ AVR32 0 RL78 0 R32C 0
|
||||
/ PIC18 0/1 SH-2 0 M16C 0/1
|
||||
/ PIC24 0 H8S 0 MSP430 0
|
||||
/ PIC32 0 H8/300H 0 8051 0/1
|
||||
*/
|
||||
|
||||
@@ -31,4 +31,3 @@ typedef unsigned long DWORD;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3739,10 +3739,10 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
|
||||
#if !_TINY_TABLE
|
||||
if (dir) { /* OEMCP to unicode */
|
||||
p = sjis2uni;
|
||||
hi = sizeof(sjis2uni) / 4 - 1;
|
||||
hi = sizeof sjis2uni / 4 - 1;
|
||||
} else { /* Unicode to OEMCP */
|
||||
p = uni2sjis;
|
||||
hi = sizeof(uni2sjis) / 4 - 1;
|
||||
hi = sizeof uni2sjis / 4 - 1;
|
||||
}
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
@@ -3764,7 +3764,7 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
|
||||
p -= 3;
|
||||
c = *p;
|
||||
} else { /* Unicode to OEMCP */
|
||||
li = 0; hi = sizeof(uni2sjis) / 4 - 1;
|
||||
li = 0; hi = sizeof uni2sjis / 4 - 1;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (chr == uni2sjis[i * 2]) break;
|
||||
@@ -10936,10 +10936,10 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
|
||||
} else {
|
||||
if (dir) { /* OEMCP to unicode */
|
||||
p = oem2uni;
|
||||
hi = sizeof(oem2uni) / 4 - 1;
|
||||
hi = sizeof oem2uni / 4 - 1;
|
||||
} else { /* Unicode to OEMCP */
|
||||
p = uni2oem;
|
||||
hi = sizeof(uni2oem) / 4 - 1;
|
||||
hi = sizeof uni2oem / 4 - 1;
|
||||
}
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
@@ -8565,10 +8565,10 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
|
||||
} else {
|
||||
if (dir) { /* OEMCP to unicode */
|
||||
p = oem2uni;
|
||||
hi = sizeof(oem2uni) / 4 - 1;
|
||||
hi = sizeof oem2uni / 4 - 1;
|
||||
} else { /* Unicode to OEMCP */
|
||||
p = uni2oem;
|
||||
hi = sizeof(uni2oem) / 4 - 1;
|
||||
hi = sizeof uni2oem / 4 - 1;
|
||||
}
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
@@ -6791,10 +6791,10 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
|
||||
} else {
|
||||
if (dir) { /* OEMCP to unicode */
|
||||
p = oem2uni;
|
||||
hi = sizeof(oem2uni) / 4 - 1;
|
||||
hi = sizeof oem2uni / 4 - 1;
|
||||
} else { /* Unicode to OEMCP */
|
||||
p = uni2oem;
|
||||
hi = sizeof(uni2oem) / 4 - 1;
|
||||
hi = sizeof uni2oem / 4 - 1;
|
||||
}
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
151
lib/fatfs/option/syscall.c
Normal file
151
lib/fatfs/option/syscall.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample code of OS dependent controls for FatFs */
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "../ff.h"
|
||||
|
||||
|
||||
#if _FS_REENTRANT
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
|
||||
BYTE vol, /* Corresponding logical drive being processed */
|
||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
||||
ret = (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
|
||||
// ret = 1; /* The initial value of the semaphore must be 1. */
|
||||
|
||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
|
||||
// ret = (int)(*sobj != NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj function. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
|
||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
ret = CloseHandle(sobj); /* Win32 */
|
||||
|
||||
// ret = 1; /* uITRON (nothing to do) */
|
||||
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
// vSemaphoreDelete(sobj); /* FreeRTOS */
|
||||
// ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||
_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
||||
|
||||
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
|
||||
|
||||
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
// ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
ReleaseMutex(sobj); /* Win32 */
|
||||
|
||||
// sig_sem(sobj); /* uITRON */
|
||||
|
||||
// OSMutexPost(sobj); /* uC/OS-II */
|
||||
|
||||
// xSemaphoreGive(sobj); /* FreeRTOS */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||
*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Discard the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
17
lib/fatfs/option/unicode.c
Normal file
17
lib/fatfs/option/unicode.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "../ff.h"
|
||||
|
||||
#if _USE_LFN != 0
|
||||
|
||||
#if _CODE_PAGE == 932 /* Japanese Shift_JIS */
|
||||
#include "cc932.c"
|
||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||
#include "cc936.c"
|
||||
#elif _CODE_PAGE == 949 /* Korean */
|
||||
#include "cc949.c"
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#include "cc950.c"
|
||||
#else /* Small character-set */
|
||||
#include "ccsbcs.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
32
lib/libm/acoshf.c
Normal file
32
lib/libm/acoshf.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
// acoshf from musl-0.9.15
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if FLT_EVAL_METHOD==2
|
||||
#undef sqrtf
|
||||
#define sqrtf sqrtl
|
||||
#elif FLT_EVAL_METHOD==1
|
||||
#undef sqrtf
|
||||
#define sqrtf sqrt
|
||||
#endif
|
||||
|
||||
/* acosh(x) = log(x + sqrt(x*x-1)) */
|
||||
float acoshf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
uint32_t a = u.i & 0x7fffffff;
|
||||
|
||||
if (a < 0x3f800000+(1<<23))
|
||||
/* |x| < 2, invalid if x < 1 or nan */
|
||||
/* up to 2ulp error in [1,1.125] */
|
||||
return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1)));
|
||||
if (a < 0x3f800000+(12<<23))
|
||||
/* |x| < 0x1p12 */
|
||||
return logf(2*x - 1/(x+sqrtf(x*x-1)));
|
||||
/* x >= 0x1p12 */
|
||||
return logf(x) + 0.693147180559945309417232121458176568f;
|
||||
}
|
||||
34
lib/libm/asinhf.c
Normal file
34
lib/libm/asinhf.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
// asinhf from musl-0.9.15
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
|
||||
float asinhf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {.f = x};
|
||||
uint32_t i = u.i & 0x7fffffff;
|
||||
unsigned s = u.i >> 31;
|
||||
|
||||
/* |x| */
|
||||
u.i = i;
|
||||
x = u.f;
|
||||
|
||||
if (i >= 0x3f800000 + (12<<23)) {
|
||||
/* |x| >= 0x1p12 or inf or nan */
|
||||
x = logf(x) + 0.693147180559945309417232121458176568f;
|
||||
} else if (i >= 0x3f800000 + (1<<23)) {
|
||||
/* |x| >= 2 */
|
||||
x = logf(2*x + 1/(sqrtf(x*x+1)+x));
|
||||
} else if (i >= 0x3f800000 - (12<<23)) {
|
||||
/* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */
|
||||
x = log1pf(x + x*x/(sqrtf(x*x+1)+1));
|
||||
} else {
|
||||
/* |x| < 0x1p-12, raise inexact if x!=0 */
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
}
|
||||
return s ? -x : x;
|
||||
}
|
||||
34
lib/libm/atanhf.c
Normal file
34
lib/libm/atanhf.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
// atanhf from musl-0.9.15
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
|
||||
float atanhf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {.f = x};
|
||||
unsigned s = u.i >> 31;
|
||||
float_t y;
|
||||
|
||||
/* |x| */
|
||||
u.i &= 0x7fffffff;
|
||||
y = u.f;
|
||||
|
||||
if (u.i < 0x3f800000 - (1<<23)) {
|
||||
if (u.i < 0x3f800000 - (32<<23)) {
|
||||
/* handle underflow */
|
||||
if (u.i < (1<<23))
|
||||
FORCE_EVAL((float)(y*y));
|
||||
} else {
|
||||
/* |x| < 0.5, up to 1.7ulp error */
|
||||
y = 0.5f*log1pf(2*y + 2*y*y/(1-y));
|
||||
}
|
||||
} else {
|
||||
/* avoid overflow */
|
||||
y = 0.5f*log1pf(2*(y/(1-y)));
|
||||
}
|
||||
return s ? -y : y;
|
||||
}
|
||||
202
lib/libm/ef_rem_pio2.c
Normal file
202
lib/libm/ef_rem_pio2.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* ef_rem_pio2.c -- float version of e_rem_pio2.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
*/
|
||||
|
||||
/* __ieee754_rem_pio2f(x,y)
|
||||
*
|
||||
* return the remainder of x rem pi/2 in y[0]+y[1]
|
||||
* use __kernel_rem_pio2f()
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
/*
|
||||
* Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
static const __int32_t two_over_pi[] = {
|
||||
#else
|
||||
static __int32_t two_over_pi[] = {
|
||||
#endif
|
||||
0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC,
|
||||
0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62,
|
||||
0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63,
|
||||
0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A,
|
||||
0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09,
|
||||
0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29,
|
||||
0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44,
|
||||
0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41,
|
||||
0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C,
|
||||
0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8,
|
||||
0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11,
|
||||
0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF,
|
||||
0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E,
|
||||
0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5,
|
||||
0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92,
|
||||
0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08,
|
||||
0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0,
|
||||
0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3,
|
||||
0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85,
|
||||
0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80,
|
||||
0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA,
|
||||
0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B,
|
||||
};
|
||||
|
||||
/* This array is like the one in e_rem_pio2.c, but the numbers are
|
||||
single precision and the last 8 bits are forced to 0. */
|
||||
#ifdef __STDC__
|
||||
static const __int32_t npio2_hw[] = {
|
||||
#else
|
||||
static __int32_t npio2_hw[] = {
|
||||
#endif
|
||||
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
|
||||
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
|
||||
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
|
||||
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
|
||||
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
|
||||
0x4242c700, 0x42490f00
|
||||
};
|
||||
|
||||
/*
|
||||
* invpio2: 24 bits of 2/pi
|
||||
* pio2_1: first 17 bit of pi/2
|
||||
* pio2_1t: pi/2 - pio2_1
|
||||
* pio2_2: second 17 bit of pi/2
|
||||
* pio2_2t: pi/2 - (pio2_1+pio2_2)
|
||||
* pio2_3: third 17 bit of pi/2
|
||||
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
|
||||
*/
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float
|
||||
#else
|
||||
static float
|
||||
#endif
|
||||
zero = 0.0000000000e+00, /* 0x00000000 */
|
||||
half = 5.0000000000e-01, /* 0x3f000000 */
|
||||
two8 = 2.5600000000e+02, /* 0x43800000 */
|
||||
invpio2 = 6.3661980629e-01, /* 0x3f22f984 */
|
||||
pio2_1 = 1.5707855225e+00, /* 0x3fc90f80 */
|
||||
pio2_1t = 1.0804334124e-05, /* 0x37354443 */
|
||||
pio2_2 = 1.0804273188e-05, /* 0x37354400 */
|
||||
pio2_2t = 6.0770999344e-11, /* 0x2e85a308 */
|
||||
pio2_3 = 6.0770943833e-11, /* 0x2e85a300 */
|
||||
pio2_3t = 6.1232342629e-17; /* 0x248d3132 */
|
||||
|
||||
#ifdef __STDC__
|
||||
__int32_t __ieee754_rem_pio2f(float x, float *y)
|
||||
#else
|
||||
__int32_t __ieee754_rem_pio2f(x,y)
|
||||
float x,y[];
|
||||
#endif
|
||||
{
|
||||
float z,w,t,r,fn;
|
||||
float tx[3];
|
||||
__int32_t i,j,n,ix,hx;
|
||||
int e0,nx;
|
||||
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
ix = hx&0x7fffffff;
|
||||
if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */
|
||||
{y[0] = x; y[1] = 0; return 0;}
|
||||
if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
|
||||
if(hx>0) {
|
||||
z = x - pio2_1;
|
||||
if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
|
||||
y[0] = z - pio2_1t;
|
||||
y[1] = (z-y[0])-pio2_1t;
|
||||
} else { /* near pi/2, use 24+24+24 bit pi */
|
||||
z -= pio2_2;
|
||||
y[0] = z - pio2_2t;
|
||||
y[1] = (z-y[0])-pio2_2t;
|
||||
}
|
||||
return 1;
|
||||
} else { /* negative x */
|
||||
z = x + pio2_1;
|
||||
if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
|
||||
y[0] = z + pio2_1t;
|
||||
y[1] = (z-y[0])+pio2_1t;
|
||||
} else { /* near pi/2, use 24+24+24 bit pi */
|
||||
z += pio2_2;
|
||||
y[0] = z + pio2_2t;
|
||||
y[1] = (z-y[0])+pio2_2t;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
|
||||
t = fabsf(x);
|
||||
n = (__int32_t) (t*invpio2+half);
|
||||
fn = (float)n;
|
||||
r = t-fn*pio2_1;
|
||||
w = fn*pio2_1t; /* 1st round good to 40 bit */
|
||||
if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) {
|
||||
y[0] = r-w; /* quick check no cancellation */
|
||||
} else {
|
||||
__uint32_t high;
|
||||
j = ix>>23;
|
||||
y[0] = r-w;
|
||||
GET_FLOAT_WORD(high,y[0]);
|
||||
i = j-((high>>23)&0xff);
|
||||
if(i>8) { /* 2nd iteration needed, good to 57 */
|
||||
t = r;
|
||||
w = fn*pio2_2;
|
||||
r = t-w;
|
||||
w = fn*pio2_2t-((t-r)-w);
|
||||
y[0] = r-w;
|
||||
GET_FLOAT_WORD(high,y[0]);
|
||||
i = j-((high>>23)&0xff);
|
||||
if(i>25) { /* 3rd iteration need, 74 bits acc */
|
||||
t = r; /* will cover all possible cases */
|
||||
w = fn*pio2_3;
|
||||
r = t-w;
|
||||
w = fn*pio2_3t-((t-r)-w);
|
||||
y[0] = r-w;
|
||||
}
|
||||
}
|
||||
}
|
||||
y[1] = (r-y[0])-w;
|
||||
if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
|
||||
else return n;
|
||||
}
|
||||
/*
|
||||
* all other (large) arguments
|
||||
*/
|
||||
if(!FLT_UWORD_IS_FINITE(ix)) {
|
||||
y[0]=y[1]=x-x; return 0;
|
||||
}
|
||||
/* set z = scalbn(|x|,ilogb(x)-7) */
|
||||
e0 = (int)((ix>>23)-134); /* e0 = ilogb(z)-7; */
|
||||
SET_FLOAT_WORD(z, ix - ((__int32_t)e0<<23));
|
||||
for(i=0;i<2;i++) {
|
||||
tx[i] = (float)((__int32_t)(z));
|
||||
z = (z-tx[i])*two8;
|
||||
}
|
||||
tx[2] = z;
|
||||
nx = 3;
|
||||
while(tx[nx-1]==zero) nx--; /* skip zero term */
|
||||
n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi);
|
||||
if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
|
||||
return n;
|
||||
}
|
||||
227
lib/libm/fdlibm.h
Normal file
227
lib/libm/fdlibm.h
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* This file is adapted from from newlib-nano-2, the newlib/libm/common/fdlib.h,
|
||||
* available from https://github.com/32bitmicro/newlib-nano-2. The main change
|
||||
* is removal of anything to do with double precision.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* @(#)fdlibm.h 5.1 93/09/24 */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* Default to XOPEN_MODE. */
|
||||
#define _XOPEN_MODE
|
||||
|
||||
/* Most routines need to check whether a float is finite, infinite, or not a
|
||||
number, and many need to know whether the result of an operation will
|
||||
overflow. These conditions depend on whether the largest exponent is
|
||||
used for NaNs & infinities, or whether it's used for finite numbers. The
|
||||
macros below wrap up that kind of information:
|
||||
|
||||
FLT_UWORD_IS_FINITE(X)
|
||||
True if a positive float with bitmask X is finite.
|
||||
|
||||
FLT_UWORD_IS_NAN(X)
|
||||
True if a positive float with bitmask X is not a number.
|
||||
|
||||
FLT_UWORD_IS_INFINITE(X)
|
||||
True if a positive float with bitmask X is +infinity.
|
||||
|
||||
FLT_UWORD_MAX
|
||||
The bitmask of FLT_MAX.
|
||||
|
||||
FLT_UWORD_HALF_MAX
|
||||
The bitmask of FLT_MAX/2.
|
||||
|
||||
FLT_UWORD_EXP_MAX
|
||||
The bitmask of the largest finite exponent (129 if the largest
|
||||
exponent is used for finite numbers, 128 otherwise).
|
||||
|
||||
FLT_UWORD_LOG_MAX
|
||||
The bitmask of log(FLT_MAX), rounded down. This value is the largest
|
||||
input that can be passed to exp() without producing overflow.
|
||||
|
||||
FLT_UWORD_LOG_2MAX
|
||||
The bitmask of log(2*FLT_MAX), rounded down. This value is the
|
||||
largest input than can be passed to cosh() without producing
|
||||
overflow.
|
||||
|
||||
FLT_LARGEST_EXP
|
||||
The largest biased exponent that can be used for finite numbers
|
||||
(255 if the largest exponent is used for finite numbers, 254
|
||||
otherwise) */
|
||||
|
||||
#ifdef _FLT_LARGEST_EXPONENT_IS_NORMAL
|
||||
#define FLT_UWORD_IS_FINITE(x) 1
|
||||
#define FLT_UWORD_IS_NAN(x) 0
|
||||
#define FLT_UWORD_IS_INFINITE(x) 0
|
||||
#define FLT_UWORD_MAX 0x7fffffff
|
||||
#define FLT_UWORD_EXP_MAX 0x43010000
|
||||
#define FLT_UWORD_LOG_MAX 0x42b2d4fc
|
||||
#define FLT_UWORD_LOG_2MAX 0x42b437e0
|
||||
#define HUGE ((float)0X1.FFFFFEP128)
|
||||
#else
|
||||
#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L)
|
||||
#define FLT_UWORD_IS_NAN(x) ((x)>0x7f800000L)
|
||||
#define FLT_UWORD_IS_INFINITE(x) ((x)==0x7f800000L)
|
||||
#define FLT_UWORD_MAX 0x7f7fffffL
|
||||
#define FLT_UWORD_EXP_MAX 0x43000000
|
||||
#define FLT_UWORD_LOG_MAX 0x42b17217
|
||||
#define FLT_UWORD_LOG_2MAX 0x42b2d4fc
|
||||
#define HUGE ((float)3.40282346638528860e+38)
|
||||
#endif
|
||||
#define FLT_UWORD_HALF_MAX (FLT_UWORD_MAX-(1L<<23))
|
||||
#define FLT_LARGEST_EXP (FLT_UWORD_MAX>>23)
|
||||
|
||||
/* Many routines check for zero and subnormal numbers. Such things depend
|
||||
on whether the target supports denormals or not:
|
||||
|
||||
FLT_UWORD_IS_ZERO(X)
|
||||
True if a positive float with bitmask X is +0. Without denormals,
|
||||
any float with a zero exponent is a +0 representation. With
|
||||
denormals, the only +0 representation is a 0 bitmask.
|
||||
|
||||
FLT_UWORD_IS_SUBNORMAL(X)
|
||||
True if a non-zero positive float with bitmask X is subnormal.
|
||||
(Routines should check for zeros first.)
|
||||
|
||||
FLT_UWORD_MIN
|
||||
The bitmask of the smallest float above +0. Call this number
|
||||
REAL_FLT_MIN...
|
||||
|
||||
FLT_UWORD_EXP_MIN
|
||||
The bitmask of the float representation of REAL_FLT_MIN's exponent.
|
||||
|
||||
FLT_UWORD_LOG_MIN
|
||||
The bitmask of |log(REAL_FLT_MIN)|, rounding down.
|
||||
|
||||
FLT_SMALLEST_EXP
|
||||
REAL_FLT_MIN's exponent - EXP_BIAS (1 if denormals are not supported,
|
||||
-22 if they are).
|
||||
*/
|
||||
|
||||
#ifdef _FLT_NO_DENORMALS
|
||||
#define FLT_UWORD_IS_ZERO(x) ((x)<0x00800000L)
|
||||
#define FLT_UWORD_IS_SUBNORMAL(x) 0
|
||||
#define FLT_UWORD_MIN 0x00800000
|
||||
#define FLT_UWORD_EXP_MIN 0x42fc0000
|
||||
#define FLT_UWORD_LOG_MIN 0x42aeac50
|
||||
#define FLT_SMALLEST_EXP 1
|
||||
#else
|
||||
#define FLT_UWORD_IS_ZERO(x) ((x)==0)
|
||||
#define FLT_UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L)
|
||||
#define FLT_UWORD_MIN 0x00000001
|
||||
#define FLT_UWORD_EXP_MIN 0x43160000
|
||||
#define FLT_UWORD_LOG_MIN 0x42cff1b5
|
||||
#define FLT_SMALLEST_EXP -22
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#undef __P
|
||||
#define __P(p) p
|
||||
#else
|
||||
#define __P(p) ()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
|
||||
* (one may replace the following line by "#include <values.h>")
|
||||
*/
|
||||
|
||||
#define X_TLOSS 1.41484755040568800000e+16
|
||||
|
||||
/* Functions that are not documented, and are not in <math.h>. */
|
||||
|
||||
/* Undocumented float functions. */
|
||||
#ifdef _SCALB_INT
|
||||
extern float scalbf __P((float, int));
|
||||
#else
|
||||
extern float scalbf __P((float, float));
|
||||
#endif
|
||||
extern float significandf __P((float));
|
||||
|
||||
/* ieee style elementary float functions */
|
||||
extern float __ieee754_sqrtf __P((float));
|
||||
extern float __ieee754_acosf __P((float));
|
||||
extern float __ieee754_acoshf __P((float));
|
||||
extern float __ieee754_logf __P((float));
|
||||
extern float __ieee754_atanhf __P((float));
|
||||
extern float __ieee754_asinf __P((float));
|
||||
extern float __ieee754_atan2f __P((float,float));
|
||||
extern float __ieee754_expf __P((float));
|
||||
extern float __ieee754_coshf __P((float));
|
||||
extern float __ieee754_fmodf __P((float,float));
|
||||
extern float __ieee754_powf __P((float,float));
|
||||
extern float __ieee754_lgammaf_r __P((float,int *));
|
||||
extern float __ieee754_gammaf_r __P((float,int *));
|
||||
extern float __ieee754_log10f __P((float));
|
||||
extern float __ieee754_sinhf __P((float));
|
||||
extern float __ieee754_hypotf __P((float,float));
|
||||
extern float __ieee754_j0f __P((float));
|
||||
extern float __ieee754_j1f __P((float));
|
||||
extern float __ieee754_y0f __P((float));
|
||||
extern float __ieee754_y1f __P((float));
|
||||
extern float __ieee754_jnf __P((int,float));
|
||||
extern float __ieee754_ynf __P((int,float));
|
||||
extern float __ieee754_remainderf __P((float,float));
|
||||
extern __int32_t __ieee754_rem_pio2f __P((float,float*));
|
||||
#ifdef _SCALB_INT
|
||||
extern float __ieee754_scalbf __P((float,int));
|
||||
#else
|
||||
extern float __ieee754_scalbf __P((float,float));
|
||||
#endif
|
||||
|
||||
/* float versions of fdlibm kernel functions */
|
||||
extern float __kernel_sinf __P((float,float,int));
|
||||
extern float __kernel_cosf __P((float,float));
|
||||
extern float __kernel_tanf __P((float,float,int));
|
||||
extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const __int32_t*));
|
||||
|
||||
/* A union which permits us to convert between a float and a 32 bit
|
||||
int. */
|
||||
|
||||
typedef union
|
||||
{
|
||||
float value;
|
||||
__uint32_t word;
|
||||
} ieee_float_shape_type;
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
|
||||
#define GET_FLOAT_WORD(i,d) \
|
||||
do { \
|
||||
ieee_float_shape_type gf_u; \
|
||||
gf_u.value = (d); \
|
||||
(i) = gf_u.word; \
|
||||
} while (0)
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
|
||||
#define SET_FLOAT_WORD(d,i) \
|
||||
do { \
|
||||
ieee_float_shape_type sf_u; \
|
||||
sf_u.word = (i); \
|
||||
(d) = sf_u.value; \
|
||||
} while (0)
|
||||
|
||||
/* Macros to avoid undefined behaviour that can arise if the amount
|
||||
of a shift is exactly equal to the size of the shifted operand. */
|
||||
|
||||
#define SAFE_LEFT_SHIFT(op,amt) \
|
||||
(((amt) < 8 * sizeof(op)) ? ((op) << (amt)) : 0)
|
||||
|
||||
#define SAFE_RIGHT_SHIFT(op,amt) \
|
||||
(((amt) < 8 * sizeof(op)) ? ((op) >> (amt)) : 0)
|
||||
68
lib/libm/kf_cos.c
Normal file
68
lib/libm/kf_cos.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* kf_cos.c -- float version of k_cos.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float
|
||||
#else
|
||||
static float
|
||||
#endif
|
||||
one = 1.0000000000e+00, /* 0x3f800000 */
|
||||
C1 = 4.1666667908e-02, /* 0x3d2aaaab */
|
||||
C2 = -1.3888889225e-03, /* 0xbab60b61 */
|
||||
C3 = 2.4801587642e-05, /* 0x37d00d01 */
|
||||
C4 = -2.7557314297e-07, /* 0xb493f27c */
|
||||
C5 = 2.0875723372e-09, /* 0x310f74f6 */
|
||||
C6 = -1.1359647598e-11; /* 0xad47d74e */
|
||||
|
||||
#ifdef __STDC__
|
||||
float __kernel_cosf(float x, float y)
|
||||
#else
|
||||
float __kernel_cosf(x, y)
|
||||
float x,y;
|
||||
#endif
|
||||
{
|
||||
float a,hz,z,r,qx;
|
||||
__int32_t ix;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
ix &= 0x7fffffff; /* ix = |x|'s high word*/
|
||||
if(ix<0x32000000) { /* if x < 2**27 */
|
||||
if(((int)x)==0) return one; /* generate inexact */
|
||||
}
|
||||
z = x*x;
|
||||
r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
|
||||
if(ix < 0x3e99999a) /* if |x| < 0.3 */
|
||||
return one - ((float)0.5*z - (z*r - x*y));
|
||||
else {
|
||||
if(ix > 0x3f480000) { /* x > 0.78125 */
|
||||
qx = (float)0.28125;
|
||||
} else {
|
||||
SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */
|
||||
}
|
||||
hz = (float)0.5*z-qx;
|
||||
a = one-qx;
|
||||
return a - (hz - (z*r-x*y));
|
||||
}
|
||||
}
|
||||
217
lib/libm/kf_rem_pio2.c
Normal file
217
lib/libm/kf_rem_pio2.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* kf_rem_pio2.c -- float version of k_rem_pio2.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
/* In the float version, the input parameter x contains 8 bit
|
||||
integers, not 24 bit integers. 113 bit precision is not supported. */
|
||||
|
||||
#ifdef __STDC__
|
||||
static const int init_jk[] = {4,7,9}; /* initial value for jk */
|
||||
#else
|
||||
static int init_jk[] = {4,7,9};
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float PIo2[] = {
|
||||
#else
|
||||
static float PIo2[] = {
|
||||
#endif
|
||||
1.5703125000e+00, /* 0x3fc90000 */
|
||||
4.5776367188e-04, /* 0x39f00000 */
|
||||
2.5987625122e-05, /* 0x37da0000 */
|
||||
7.5437128544e-08, /* 0x33a20000 */
|
||||
6.0026650317e-11, /* 0x2e840000 */
|
||||
7.3896444519e-13, /* 0x2b500000 */
|
||||
5.3845816694e-15, /* 0x27c20000 */
|
||||
5.6378512969e-18, /* 0x22d00000 */
|
||||
8.3009228831e-20, /* 0x1fc40000 */
|
||||
3.2756352257e-22, /* 0x1bc60000 */
|
||||
6.3331015649e-25, /* 0x17440000 */
|
||||
};
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float
|
||||
#else
|
||||
static float
|
||||
#endif
|
||||
zero = 0.0,
|
||||
one = 1.0,
|
||||
two8 = 2.5600000000e+02, /* 0x43800000 */
|
||||
twon8 = 3.9062500000e-03; /* 0x3b800000 */
|
||||
|
||||
#ifdef __STDC__
|
||||
int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const __int32_t *ipio2)
|
||||
#else
|
||||
int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2)
|
||||
float x[], y[]; int e0,nx,prec; __int32_t ipio2[];
|
||||
#endif
|
||||
{
|
||||
__int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
|
||||
float z,fw,f[20],fq[20],q[20];
|
||||
|
||||
/* initialize jk*/
|
||||
jk = init_jk[prec];
|
||||
jp = jk;
|
||||
|
||||
/* determine jx,jv,q0, note that 3>q0 */
|
||||
jx = nx-1;
|
||||
jv = (e0-3)/8; if(jv<0) jv=0;
|
||||
q0 = e0-8*(jv+1);
|
||||
|
||||
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
|
||||
j = jv-jx; m = jx+jk;
|
||||
for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j];
|
||||
|
||||
/* compute q[0],q[1],...q[jk] */
|
||||
for (i=0;i<=jk;i++) {
|
||||
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
|
||||
}
|
||||
|
||||
jz = jk;
|
||||
recompute:
|
||||
/* distill q[] into iq[] reversingly */
|
||||
for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
|
||||
fw = (float)((__int32_t)(twon8* z));
|
||||
iq[i] = (__int32_t)(z-two8*fw);
|
||||
z = q[j-1]+fw;
|
||||
}
|
||||
|
||||
/* compute n */
|
||||
z = scalbnf(z,(int)q0); /* actual value of z */
|
||||
z -= (float)8.0*floorf(z*(float)0.125); /* trim off integer >= 8 */
|
||||
n = (__int32_t) z;
|
||||
z -= (float)n;
|
||||
ih = 0;
|
||||
if(q0>0) { /* need iq[jz-1] to determine n */
|
||||
i = (iq[jz-1]>>(8-q0)); n += i;
|
||||
iq[jz-1] -= i<<(8-q0);
|
||||
ih = iq[jz-1]>>(7-q0);
|
||||
}
|
||||
else if(q0==0) ih = iq[jz-1]>>8;
|
||||
else if(z>=(float)0.5) ih=2;
|
||||
|
||||
if(ih>0) { /* q > 0.5 */
|
||||
n += 1; carry = 0;
|
||||
for(i=0;i<jz ;i++) { /* compute 1-q */
|
||||
j = iq[i];
|
||||
if(carry==0) {
|
||||
if(j!=0) {
|
||||
carry = 1; iq[i] = 0x100- j;
|
||||
}
|
||||
} else iq[i] = 0xff - j;
|
||||
}
|
||||
if(q0>0) { /* rare case: chance is 1 in 12 */
|
||||
switch(q0) {
|
||||
case 1:
|
||||
iq[jz-1] &= 0x7f; break;
|
||||
case 2:
|
||||
iq[jz-1] &= 0x3f; break;
|
||||
}
|
||||
}
|
||||
if(ih==2) {
|
||||
z = one - z;
|
||||
if(carry!=0) z -= scalbnf(one,(int)q0);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if recomputation is needed */
|
||||
if(z==zero) {
|
||||
j = 0;
|
||||
for (i=jz-1;i>=jk;i--) j |= iq[i];
|
||||
if(j==0) { /* need recomputation */
|
||||
for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
|
||||
|
||||
for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
|
||||
f[jx+i] = (float) ipio2[jv+i];
|
||||
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
|
||||
q[i] = fw;
|
||||
}
|
||||
jz += k;
|
||||
goto recompute;
|
||||
}
|
||||
}
|
||||
|
||||
/* chop off zero terms */
|
||||
if(z==(float)0.0) {
|
||||
jz -= 1; q0 -= 8;
|
||||
while(iq[jz]==0) { jz--; q0-=8;}
|
||||
} else { /* break z into 8-bit if necessary */
|
||||
z = scalbnf(z,-(int)q0);
|
||||
if(z>=two8) {
|
||||
fw = (float)((__int32_t)(twon8*z));
|
||||
iq[jz] = (__int32_t)(z-two8*fw);
|
||||
jz += 1; q0 += 8;
|
||||
iq[jz] = (__int32_t) fw;
|
||||
} else iq[jz] = (__int32_t) z ;
|
||||
}
|
||||
|
||||
/* convert integer "bit" chunk to floating-point value */
|
||||
fw = scalbnf(one,(int)q0);
|
||||
for(i=jz;i>=0;i--) {
|
||||
q[i] = fw*(float)iq[i]; fw*=twon8;
|
||||
}
|
||||
|
||||
/* compute PIo2[0,...,jp]*q[jz,...,0] */
|
||||
for(i=jz;i>=0;i--) {
|
||||
for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
|
||||
fq[jz-i] = fw;
|
||||
}
|
||||
|
||||
/* compress fq[] into y[] */
|
||||
switch(prec) {
|
||||
case 0:
|
||||
fw = 0.0;
|
||||
for (i=jz;i>=0;i--) fw += fq[i];
|
||||
y[0] = (ih==0)? fw: -fw;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
fw = 0.0;
|
||||
for (i=jz;i>=0;i--) fw += fq[i];
|
||||
y[0] = (ih==0)? fw: -fw;
|
||||
fw = fq[0]-fw;
|
||||
for (i=1;i<=jz;i++) fw += fq[i];
|
||||
y[1] = (ih==0)? fw: -fw;
|
||||
break;
|
||||
case 3: /* painful */
|
||||
for (i=jz;i>0;i--) {
|
||||
fw = fq[i-1]+fq[i];
|
||||
fq[i] += fq[i-1]-fw;
|
||||
fq[i-1] = fw;
|
||||
}
|
||||
for (i=jz;i>1;i--) {
|
||||
fw = fq[i-1]+fq[i];
|
||||
fq[i] += fq[i-1]-fw;
|
||||
fq[i-1] = fw;
|
||||
}
|
||||
for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
|
||||
if(ih==0) {
|
||||
y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
|
||||
} else {
|
||||
y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
|
||||
}
|
||||
}
|
||||
return n&7;
|
||||
}
|
||||
58
lib/libm/kf_sin.c
Normal file
58
lib/libm/kf_sin.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* kf_sin.c -- float version of k_sin.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float
|
||||
#else
|
||||
static float
|
||||
#endif
|
||||
half = 5.0000000000e-01,/* 0x3f000000 */
|
||||
S1 = -1.6666667163e-01, /* 0xbe2aaaab */
|
||||
S2 = 8.3333337680e-03, /* 0x3c088889 */
|
||||
S3 = -1.9841270114e-04, /* 0xb9500d01 */
|
||||
S4 = 2.7557314297e-06, /* 0x3638ef1b */
|
||||
S5 = -2.5050759689e-08, /* 0xb2d72f34 */
|
||||
S6 = 1.5896910177e-10; /* 0x2f2ec9d3 */
|
||||
|
||||
#ifdef __STDC__
|
||||
float __kernel_sinf(float x, float y, int iy)
|
||||
#else
|
||||
float __kernel_sinf(x, y, iy)
|
||||
float x,y; int iy; /* iy=0 if y is zero */
|
||||
#endif
|
||||
{
|
||||
float z,r,v;
|
||||
__int32_t ix;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
ix &= 0x7fffffff; /* high word of x */
|
||||
if(ix<0x32000000) /* |x| < 2**-27 */
|
||||
{if((int)x==0) return x;} /* generate inexact */
|
||||
z = x*x;
|
||||
v = z*x;
|
||||
r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
|
||||
if(iy==0) return x+v*(S1+z*r);
|
||||
else return x-((z*(half*y-v*r)-y)-v*S1);
|
||||
}
|
||||
105
lib/libm/kf_tan.c
Normal file
105
lib/libm/kf_tan.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* kf_tan.c -- float version of k_tan.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
#ifdef __STDC__
|
||||
static const float
|
||||
#else
|
||||
static float
|
||||
#endif
|
||||
one = 1.0000000000e+00, /* 0x3f800000 */
|
||||
pio4 = 7.8539812565e-01, /* 0x3f490fda */
|
||||
pio4lo= 3.7748947079e-08, /* 0x33222168 */
|
||||
T[] = {
|
||||
3.3333334327e-01, /* 0x3eaaaaab */
|
||||
1.3333334029e-01, /* 0x3e088889 */
|
||||
5.3968254477e-02, /* 0x3d5d0dd1 */
|
||||
2.1869488060e-02, /* 0x3cb327a4 */
|
||||
8.8632395491e-03, /* 0x3c11371f */
|
||||
3.5920790397e-03, /* 0x3b6b6916 */
|
||||
1.4562094584e-03, /* 0x3abede48 */
|
||||
5.8804126456e-04, /* 0x3a1a26c8 */
|
||||
2.4646313977e-04, /* 0x398137b9 */
|
||||
7.8179444245e-05, /* 0x38a3f445 */
|
||||
7.1407252108e-05, /* 0x3895c07a */
|
||||
-1.8558637748e-05, /* 0xb79bae5f */
|
||||
2.5907305826e-05, /* 0x37d95384 */
|
||||
};
|
||||
|
||||
#ifdef __STDC__
|
||||
float __kernel_tanf(float x, float y, int iy)
|
||||
#else
|
||||
float __kernel_tanf(x, y, iy)
|
||||
float x,y; int iy;
|
||||
#endif
|
||||
{
|
||||
float z,r,v,w,s;
|
||||
__int32_t ix,hx;
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
ix = hx&0x7fffffff; /* high word of |x| */
|
||||
if(ix<0x31800000) /* x < 2**-28 */
|
||||
{if((int)x==0) { /* generate inexact */
|
||||
if((ix|(iy+1))==0) return one/fabsf(x);
|
||||
else return (iy==1)? x: -one/x;
|
||||
}
|
||||
}
|
||||
if(ix>=0x3f2ca140) { /* |x|>=0.6744 */
|
||||
if(hx<0) {x = -x; y = -y;}
|
||||
z = pio4-x;
|
||||
w = pio4lo-y;
|
||||
x = z+w; y = 0.0;
|
||||
}
|
||||
z = x*x;
|
||||
w = z*z;
|
||||
/* Break x^5*(T[1]+x^2*T[2]+...) into
|
||||
* x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
|
||||
* x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
|
||||
*/
|
||||
r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
|
||||
v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
|
||||
s = z*x;
|
||||
r = y + z*(s*(r+v)+y);
|
||||
r += T[0]*s;
|
||||
w = x+r;
|
||||
if(ix>=0x3f2ca140) {
|
||||
v = (float)iy;
|
||||
return (float)(1-((hx>>30)&2))*(v-(float)2.0*(x-(w*w/(w+v)-r)));
|
||||
}
|
||||
if(iy==1) return w;
|
||||
else { /* if allow error up to 2 ulp,
|
||||
simply return -1.0/(x+r) here */
|
||||
/* compute -1.0/(x+r) accurately */
|
||||
float a,t;
|
||||
__int32_t i;
|
||||
z = w;
|
||||
GET_FLOAT_WORD(i,z);
|
||||
SET_FLOAT_WORD(z,i&0xfffff000);
|
||||
v = r-(z - x); /* z+v = r+x */
|
||||
t = a = -(float)1.0/w; /* a = -1.0/w */
|
||||
GET_FLOAT_WORD(i,t);
|
||||
SET_FLOAT_WORD(t,i&0xfffff000);
|
||||
s = (float)1.0+t*z;
|
||||
return t+a*(s+t*v);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#define FLT_EVAL_METHOD 0
|
||||
|
||||
#define FORCE_EVAL(x) do { \
|
||||
if (sizeof(x) == sizeof(float)) { \
|
||||
volatile float __x; \
|
||||
|
||||
83
lib/libm/log1pf.c
Normal file
83
lib/libm/log1pf.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
// log1pf from musl-0.9.15
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const float
|
||||
ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
|
||||
ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
|
||||
/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
|
||||
Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
|
||||
Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
|
||||
Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
|
||||
Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
|
||||
|
||||
float log1pf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
float_t hfsq,f,c,s,z,R,w,t1,t2,dk;
|
||||
uint32_t ix,iu;
|
||||
int k;
|
||||
|
||||
ix = u.i;
|
||||
k = 1;
|
||||
if (ix < 0x3ed413d0 || ix>>31) { /* 1+x < sqrt(2)+ */
|
||||
if (ix >= 0xbf800000) { /* x <= -1.0 */
|
||||
if (x == -1)
|
||||
return x/0.0f; /* log1p(-1)=+inf */
|
||||
return (x-x)/0.0f; /* log1p(x<-1)=NaN */
|
||||
}
|
||||
if (ix<<1 < 0x33800000<<1) { /* |x| < 2**-24 */
|
||||
/* underflow if subnormal */
|
||||
if ((ix&0x7f800000) == 0)
|
||||
FORCE_EVAL(x*x);
|
||||
return x;
|
||||
}
|
||||
if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
|
||||
k = 0;
|
||||
c = 0;
|
||||
f = x;
|
||||
}
|
||||
} else if (ix >= 0x7f800000)
|
||||
return x;
|
||||
if (k) {
|
||||
u.f = 1 + x;
|
||||
iu = u.i;
|
||||
iu += 0x3f800000 - 0x3f3504f3;
|
||||
k = (int)(iu>>23) - 0x7f;
|
||||
/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
|
||||
if (k < 25) {
|
||||
c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
|
||||
c /= u.f;
|
||||
} else
|
||||
c = 0;
|
||||
/* reduce u into [sqrt(2)/2, sqrt(2)] */
|
||||
iu = (iu&0x007fffff) + 0x3f3504f3;
|
||||
u.i = iu;
|
||||
f = u.f - 1;
|
||||
}
|
||||
s = f/(2.0f + f);
|
||||
z = s*s;
|
||||
w = z*z;
|
||||
t1= w*(Lg2+w*Lg4);
|
||||
t2= z*(Lg1+w*Lg3);
|
||||
R = t2 + t1;
|
||||
hfsq = 0.5f*f*f;
|
||||
dk = k;
|
||||
return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
|
||||
}
|
||||
@@ -49,6 +49,11 @@ double __attribute__((pcs("aapcs"))) __aeabi_i2d(int32_t x) {
|
||||
return (float)x;
|
||||
}
|
||||
|
||||
// TODO
|
||||
long long __attribute__((pcs("aapcs"))) __aeabi_f2lz(float x) {
|
||||
return (long)x;
|
||||
}
|
||||
|
||||
double __attribute__((pcs("aapcs"))) __aeabi_f2d(float x) {
|
||||
float_s_t fx={0};
|
||||
double_s_t dx={0};
|
||||
@@ -113,16 +118,10 @@ float log10f(float x) { return logf(x) / (float)_M_LN10; }
|
||||
float tanhf(float x) { return sinhf(x) / coshf(x); }
|
||||
|
||||
// TODO we need import these functions from some library (eg musl or newlib)
|
||||
float acoshf(float x) { return 0.0; }
|
||||
float asinhf(float x) { return 0.0; }
|
||||
float atanhf(float x) { return 0.0; }
|
||||
float tanf(float x) { return 0.0; }
|
||||
float tgammaf(float x) { return 0.0; }
|
||||
float lgammaf(float x) { return 0.0; }
|
||||
float erff(float x) { return 0.0; }
|
||||
float erfcf(float x) { return 0.0; }
|
||||
float modff(float x, float *y) { return 0.0; }
|
||||
float frexpf(float x, int *exp) { return 0.0; }
|
||||
float ldexpf(float x, int exp) { return 0.0; }
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -1,627 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib 2.1.0, the newlib/libm directory.
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
/* @(#)fdlibm.h 5.1 93/09/24 */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L)
|
||||
|
||||
/* A union which permits us to convert between a float and a 32 bit
|
||||
int. */
|
||||
|
||||
typedef union
|
||||
{
|
||||
float value;
|
||||
__uint32_t word;
|
||||
} ieee_float_shape_type;
|
||||
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
|
||||
#define GET_FLOAT_WORD(i,d) \
|
||||
do { \
|
||||
ieee_float_shape_type gf_u; \
|
||||
gf_u.value = (d); \
|
||||
(i) = gf_u.word; \
|
||||
} while (0)
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
|
||||
#define SET_FLOAT_WORD(d,i) \
|
||||
do { \
|
||||
ieee_float_shape_type sf_u; \
|
||||
sf_u.word = (i); \
|
||||
(d) = sf_u.value; \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/* kf_rem_pio2.c -- float version of k_rem_pio2.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
/* In the float version, the input parameter x contains 8 bit
|
||||
integers, not 24 bit integers. 113 bit precision is not supported. */
|
||||
|
||||
#ifdef __STDC__
|
||||
static const int init_jk[] = {4,7,9}; /* initial value for jk */
|
||||
#else
|
||||
static int init_jk[] = {4,7,9};
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float PIo2[] = {
|
||||
#else
|
||||
static float PIo2[] = {
|
||||
#endif
|
||||
1.5703125000e+00, /* 0x3fc90000 */
|
||||
4.5776367188e-04, /* 0x39f00000 */
|
||||
2.5987625122e-05, /* 0x37da0000 */
|
||||
7.5437128544e-08, /* 0x33a20000 */
|
||||
6.0026650317e-11, /* 0x2e840000 */
|
||||
7.3896444519e-13, /* 0x2b500000 */
|
||||
5.3845816694e-15, /* 0x27c20000 */
|
||||
5.6378512969e-18, /* 0x22d00000 */
|
||||
8.3009228831e-20, /* 0x1fc40000 */
|
||||
3.2756352257e-22, /* 0x1bc60000 */
|
||||
6.3331015649e-25, /* 0x17440000 */
|
||||
};
|
||||
|
||||
static const float
|
||||
zero = 0.0000000000e+00, /* 0x00000000 */
|
||||
one = 1.0000000000e+00, /* 0x3f800000 */
|
||||
two8 = 2.5600000000e+02, /* 0x43800000 */
|
||||
twon8 = 3.9062500000e-03; /* 0x3b800000 */
|
||||
|
||||
int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const __int32_t *ipio2)
|
||||
{
|
||||
__int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
|
||||
float z,fw,f[20],fq[20],q[20];
|
||||
|
||||
/* initialize jk*/
|
||||
jk = init_jk[prec];
|
||||
jp = jk;
|
||||
|
||||
/* determine jx,jv,q0, note that 3>q0 */
|
||||
jx = nx-1;
|
||||
jv = (e0-3)/8; if(jv<0) jv=0;
|
||||
q0 = e0-8*(jv+1);
|
||||
|
||||
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
|
||||
j = jv-jx; m = jx+jk;
|
||||
for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j];
|
||||
|
||||
/* compute q[0],q[1],...q[jk] */
|
||||
for (i=0;i<=jk;i++) {
|
||||
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
|
||||
}
|
||||
|
||||
jz = jk;
|
||||
recompute:
|
||||
/* distill q[] into iq[] reversingly */
|
||||
for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
|
||||
fw = (float)((__int32_t)(twon8* z));
|
||||
iq[i] = (__int32_t)(z-two8*fw);
|
||||
z = q[j-1]+fw;
|
||||
}
|
||||
|
||||
/* compute n */
|
||||
z = scalbnf(z,(int)q0); /* actual value of z */
|
||||
z -= (float)8.0*floorf(z*(float)0.125); /* trim off integer >= 8 */
|
||||
n = (__int32_t) z;
|
||||
z -= (float)n;
|
||||
ih = 0;
|
||||
if(q0>0) { /* need iq[jz-1] to determine n */
|
||||
i = (iq[jz-1]>>(8-q0)); n += i;
|
||||
iq[jz-1] -= i<<(8-q0);
|
||||
ih = iq[jz-1]>>(7-q0);
|
||||
}
|
||||
else if(q0==0) ih = iq[jz-1]>>8;
|
||||
else if(z>=(float)0.5) ih=2;
|
||||
|
||||
if(ih>0) { /* q > 0.5 */
|
||||
n += 1; carry = 0;
|
||||
for(i=0;i<jz ;i++) { /* compute 1-q */
|
||||
j = iq[i];
|
||||
if(carry==0) {
|
||||
if(j!=0) {
|
||||
carry = 1; iq[i] = 0x100- j;
|
||||
}
|
||||
} else iq[i] = 0xff - j;
|
||||
}
|
||||
if(q0>0) { /* rare case: chance is 1 in 12 */
|
||||
switch(q0) {
|
||||
case 1:
|
||||
iq[jz-1] &= 0x7f; break;
|
||||
case 2:
|
||||
iq[jz-1] &= 0x3f; break;
|
||||
}
|
||||
}
|
||||
if(ih==2) {
|
||||
z = one - z;
|
||||
if(carry!=0) z -= scalbnf(one,(int)q0);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if recomputation is needed */
|
||||
if(z==zero) {
|
||||
j = 0;
|
||||
for (i=jz-1;i>=jk;i--) j |= iq[i];
|
||||
if(j==0) { /* need recomputation */
|
||||
for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
|
||||
|
||||
for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
|
||||
f[jx+i] = (float) ipio2[jv+i];
|
||||
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
|
||||
q[i] = fw;
|
||||
}
|
||||
jz += k;
|
||||
goto recompute;
|
||||
}
|
||||
}
|
||||
|
||||
/* chop off zero terms */
|
||||
if(z==(float)0.0) {
|
||||
jz -= 1; q0 -= 8;
|
||||
while(iq[jz]==0) { jz--; q0-=8;}
|
||||
} else { /* break z into 8-bit if necessary */
|
||||
z = scalbnf(z,-(int)q0);
|
||||
if(z>=two8) {
|
||||
fw = (float)((__int32_t)(twon8*z));
|
||||
iq[jz] = (__int32_t)(z-two8*fw);
|
||||
jz += 1; q0 += 8;
|
||||
iq[jz] = (__int32_t) fw;
|
||||
} else iq[jz] = (__int32_t) z ;
|
||||
}
|
||||
|
||||
/* convert integer "bit" chunk to floating-point value */
|
||||
fw = scalbnf(one,(int)q0);
|
||||
for(i=jz;i>=0;i--) {
|
||||
q[i] = fw*(float)iq[i]; fw*=twon8;
|
||||
}
|
||||
|
||||
/* compute PIo2[0,...,jp]*q[jz,...,0] */
|
||||
for(i=jz;i>=0;i--) {
|
||||
for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
|
||||
fq[jz-i] = fw;
|
||||
}
|
||||
|
||||
/* compress fq[] into y[] */
|
||||
switch(prec) {
|
||||
case 0:
|
||||
fw = 0.0;
|
||||
for (i=jz;i>=0;i--) fw += fq[i];
|
||||
y[0] = (ih==0)? fw: -fw;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
fw = 0.0;
|
||||
for (i=jz;i>=0;i--) fw += fq[i];
|
||||
y[0] = (ih==0)? fw: -fw;
|
||||
fw = fq[0]-fw;
|
||||
for (i=1;i<=jz;i++) fw += fq[i];
|
||||
y[1] = (ih==0)? fw: -fw;
|
||||
break;
|
||||
case 3: /* painful */
|
||||
for (i=jz;i>0;i--) {
|
||||
fw = fq[i-1]+fq[i];
|
||||
fq[i] += fq[i-1]-fw;
|
||||
fq[i-1] = fw;
|
||||
}
|
||||
for (i=jz;i>1;i--) {
|
||||
fw = fq[i-1]+fq[i];
|
||||
fq[i] += fq[i-1]-fw;
|
||||
fq[i-1] = fw;
|
||||
}
|
||||
for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
|
||||
if(ih==0) {
|
||||
y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
|
||||
} else {
|
||||
y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
|
||||
}
|
||||
}
|
||||
return n&7;
|
||||
}
|
||||
|
||||
|
||||
/* ef_rem_pio2.c -- float version of e_rem_pio2.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
*/
|
||||
|
||||
/* __ieee754_rem_pio2f(x,y)
|
||||
*
|
||||
* return the remainder of x rem pi/2 in y[0]+y[1]
|
||||
* use __kernel_rem_pio2f()
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
|
||||
*/
|
||||
static const __int32_t two_over_pi[] = {
|
||||
0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC,
|
||||
0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62,
|
||||
0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63,
|
||||
0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A,
|
||||
0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09,
|
||||
0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29,
|
||||
0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44,
|
||||
0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41,
|
||||
0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C,
|
||||
0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8,
|
||||
0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11,
|
||||
0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF,
|
||||
0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E,
|
||||
0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5,
|
||||
0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92,
|
||||
0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08,
|
||||
0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0,
|
||||
0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3,
|
||||
0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85,
|
||||
0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80,
|
||||
0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA,
|
||||
0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B,
|
||||
};
|
||||
|
||||
/* This array is like the one in e_rem_pio2.c, but the numbers are
|
||||
single precision and the last 8 bits are forced to 0. */
|
||||
static const __int32_t npio2_hw[] = {
|
||||
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
|
||||
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
|
||||
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
|
||||
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
|
||||
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
|
||||
0x4242c700, 0x42490f00
|
||||
};
|
||||
|
||||
/*
|
||||
* invpio2: 24 bits of 2/pi
|
||||
* pio2_1: first 17 bit of pi/2
|
||||
* pio2_1t: pi/2 - pio2_1
|
||||
* pio2_2: second 17 bit of pi/2
|
||||
* pio2_2t: pi/2 - (pio2_1+pio2_2)
|
||||
* pio2_3: third 17 bit of pi/2
|
||||
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
|
||||
*/
|
||||
|
||||
static const float
|
||||
half = 5.0000000000e-01, /* 0x3f000000 */
|
||||
invpio2 = 6.3661980629e-01, /* 0x3f22f984 */
|
||||
pio2_1 = 1.5707855225e+00, /* 0x3fc90f80 */
|
||||
pio2_1t = 1.0804334124e-05, /* 0x37354443 */
|
||||
pio2_2 = 1.0804273188e-05, /* 0x37354400 */
|
||||
pio2_2t = 6.0770999344e-11, /* 0x2e85a308 */
|
||||
pio2_3 = 6.0770943833e-11, /* 0x2e85a300 */
|
||||
pio2_3t = 6.1232342629e-17; /* 0x248d3132 */
|
||||
|
||||
__int32_t __ieee754_rem_pio2f(float x, float *y)
|
||||
{
|
||||
float z,w,t,r,fn;
|
||||
float tx[3];
|
||||
__int32_t i,j,n,ix,hx;
|
||||
int e0,nx;
|
||||
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
ix = hx&0x7fffffff;
|
||||
if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */
|
||||
{y[0] = x; y[1] = 0; return 0;}
|
||||
if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
|
||||
if(hx>0) {
|
||||
z = x - pio2_1;
|
||||
if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
|
||||
y[0] = z - pio2_1t;
|
||||
y[1] = (z-y[0])-pio2_1t;
|
||||
} else { /* near pi/2, use 24+24+24 bit pi */
|
||||
z -= pio2_2;
|
||||
y[0] = z - pio2_2t;
|
||||
y[1] = (z-y[0])-pio2_2t;
|
||||
}
|
||||
return 1;
|
||||
} else { /* negative x */
|
||||
z = x + pio2_1;
|
||||
if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
|
||||
y[0] = z + pio2_1t;
|
||||
y[1] = (z-y[0])+pio2_1t;
|
||||
} else { /* near pi/2, use 24+24+24 bit pi */
|
||||
z += pio2_2;
|
||||
y[0] = z + pio2_2t;
|
||||
y[1] = (z-y[0])+pio2_2t;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
|
||||
t = fabsf(x);
|
||||
n = (__int32_t) (t*invpio2+half);
|
||||
fn = (float)n;
|
||||
r = t-fn*pio2_1;
|
||||
w = fn*pio2_1t; /* 1st round good to 40 bit */
|
||||
if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) {
|
||||
y[0] = r-w; /* quick check no cancellation */
|
||||
} else {
|
||||
__uint32_t high;
|
||||
j = ix>>23;
|
||||
y[0] = r-w;
|
||||
GET_FLOAT_WORD(high,y[0]);
|
||||
i = j-((high>>23)&0xff);
|
||||
if(i>8) { /* 2nd iteration needed, good to 57 */
|
||||
t = r;
|
||||
w = fn*pio2_2;
|
||||
r = t-w;
|
||||
w = fn*pio2_2t-((t-r)-w);
|
||||
y[0] = r-w;
|
||||
GET_FLOAT_WORD(high,y[0]);
|
||||
i = j-((high>>23)&0xff);
|
||||
if(i>25) { /* 3rd iteration need, 74 bits acc */
|
||||
t = r; /* will cover all possible cases */
|
||||
w = fn*pio2_3;
|
||||
r = t-w;
|
||||
w = fn*pio2_3t-((t-r)-w);
|
||||
y[0] = r-w;
|
||||
}
|
||||
}
|
||||
}
|
||||
y[1] = (r-y[0])-w;
|
||||
if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
|
||||
else return n;
|
||||
}
|
||||
/*
|
||||
* all other (large) arguments
|
||||
*/
|
||||
if(!FLT_UWORD_IS_FINITE(ix)) {
|
||||
y[0]=y[1]=x-x; return 0;
|
||||
}
|
||||
/* set z = scalbn(|x|,ilogb(x)-7) */
|
||||
e0 = (int)((ix>>23)-134); /* e0 = ilogb(z)-7; */
|
||||
SET_FLOAT_WORD(z, ix - ((__int32_t)e0<<23));
|
||||
for(i=0;i<2;i++) {
|
||||
tx[i] = (float)((__int32_t)(z));
|
||||
z = (z-tx[i])*two8;
|
||||
}
|
||||
tx[2] = z;
|
||||
nx = 3;
|
||||
while(tx[nx-1]==zero) nx--; /* skip zero term */
|
||||
n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi);
|
||||
if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/* kf_sin.c -- float version of k_sin.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
||||
static const float
|
||||
S1 = -1.6666667163e-01, /* 0xbe2aaaab */
|
||||
S2 = 8.3333337680e-03, /* 0x3c088889 */
|
||||
S3 = -1.9841270114e-04, /* 0xb9500d01 */
|
||||
S4 = 2.7557314297e-06, /* 0x3638ef1b */
|
||||
S5 = -2.5050759689e-08, /* 0xb2d72f34 */
|
||||
S6 = 1.5896910177e-10; /* 0x2f2ec9d3 */
|
||||
|
||||
float __kernel_sinf(float x, float y, int iy) /* iy=0 if y is zero */
|
||||
{
|
||||
float z,r,v;
|
||||
__int32_t ix;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
ix &= 0x7fffffff; /* high word of x */
|
||||
if(ix<0x32000000) /* |x| < 2**-27 */
|
||||
{if((int)x==0) return x;} /* generate inexact */
|
||||
z = x*x;
|
||||
v = z*x;
|
||||
r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
|
||||
if(iy==0) return x+v*(S1+z*r);
|
||||
else return x-((z*(half*y-v*r)-y)-v*S1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* kf_cos.c -- float version of k_cos.c
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
||||
static const float
|
||||
C1 = 4.1666667908e-02, /* 0x3d2aaaab */
|
||||
C2 = -1.3888889225e-03, /* 0xbab60b61 */
|
||||
C3 = 2.4801587642e-05, /* 0x37d00d01 */
|
||||
C4 = -2.7557314297e-07, /* 0xb493f27c */
|
||||
C5 = 2.0875723372e-09, /* 0x310f74f6 */
|
||||
C6 = -1.1359647598e-11; /* 0xad47d74e */
|
||||
|
||||
float __kernel_cosf(float x, float y)
|
||||
{
|
||||
float a,hz,z,r,qx;
|
||||
__int32_t ix;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
ix &= 0x7fffffff; /* ix = |x|'s high word*/
|
||||
if(ix<0x32000000) { /* if x < 2**27 */
|
||||
if(((int)x)==0) return one; /* generate inexact */
|
||||
}
|
||||
z = x*x;
|
||||
r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
|
||||
if(ix < 0x3e99999a) /* if |x| < 0.3 */
|
||||
return one - ((float)0.5*z - (z*r - x*y));
|
||||
else {
|
||||
if(ix > 0x3f480000) { /* x > 0.78125 */
|
||||
qx = (float)0.28125;
|
||||
} else {
|
||||
SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */
|
||||
}
|
||||
hz = (float)0.5*z-qx;
|
||||
a = one-qx;
|
||||
return a - (hz - (z*r-x*y));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* sf_sin.c -- float version of s_sin.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
||||
float sinf(float x)
|
||||
{
|
||||
float y[2],z=0.0;
|
||||
__int32_t n,ix;
|
||||
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
|
||||
/* |x| ~< pi/4 */
|
||||
ix &= 0x7fffffff;
|
||||
if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);
|
||||
|
||||
/* sin(Inf or NaN) is NaN */
|
||||
else if (!FLT_UWORD_IS_FINITE(ix)) return x-x;
|
||||
|
||||
/* argument reduction needed */
|
||||
else {
|
||||
n = __ieee754_rem_pio2f(x,y);
|
||||
switch(n&3) {
|
||||
case 0: return __kernel_sinf(y[0],y[1],1);
|
||||
case 1: return __kernel_cosf(y[0],y[1]);
|
||||
case 2: return -__kernel_sinf(y[0],y[1],1);
|
||||
default:
|
||||
return -__kernel_cosf(y[0],y[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* sf_cos.c -- float version of s_cos.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
||||
float cosf(float x)
|
||||
{
|
||||
float y[2],z=0.0;
|
||||
__int32_t n,ix;
|
||||
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
|
||||
/* |x| ~< pi/4 */
|
||||
ix &= 0x7fffffff;
|
||||
if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);
|
||||
|
||||
/* cos(Inf or NaN) is NaN */
|
||||
else if (!FLT_UWORD_IS_FINITE(ix)) return x-x;
|
||||
|
||||
/* argument reduction needed */
|
||||
else {
|
||||
n = __ieee754_rem_pio2f(x,y);
|
||||
switch(n&3) {
|
||||
case 0: return __kernel_cosf(y[0],y[1]);
|
||||
case 1: return -__kernel_sinf(y[0],y[1],1);
|
||||
case 2: return -__kernel_cosf(y[0],y[1]);
|
||||
default:
|
||||
return __kernel_sinf(y[0],y[1],1);
|
||||
}
|
||||
}
|
||||
}
|
||||
77
lib/libm/sf_cos.c
Normal file
77
lib/libm/sf_cos.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* sf_cos.c -- float version of s_cos.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float one=1.0;
|
||||
#else
|
||||
static float one=1.0;
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
float cosf(float x)
|
||||
#else
|
||||
float cosf(x)
|
||||
float x;
|
||||
#endif
|
||||
{
|
||||
float y[2],z=0.0;
|
||||
__int32_t n,ix;
|
||||
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
|
||||
/* |x| ~< pi/4 */
|
||||
ix &= 0x7fffffff;
|
||||
if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);
|
||||
|
||||
/* cos(Inf or NaN) is NaN */
|
||||
else if (!FLT_UWORD_IS_FINITE(ix)) return x-x;
|
||||
|
||||
/* argument reduction needed */
|
||||
else {
|
||||
n = __ieee754_rem_pio2f(x,y);
|
||||
switch(n&3) {
|
||||
case 0: return __kernel_cosf(y[0],y[1]);
|
||||
case 1: return -__kernel_sinf(y[0],y[1],1);
|
||||
case 2: return -__kernel_cosf(y[0],y[1]);
|
||||
default:
|
||||
return __kernel_sinf(y[0],y[1],1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DOUBLE_IS_32BITS
|
||||
|
||||
#ifdef __STDC__
|
||||
double cos(double x)
|
||||
#else
|
||||
double cos(x)
|
||||
double x;
|
||||
#endif
|
||||
{
|
||||
return (double) cosf((float) x);
|
||||
}
|
||||
|
||||
#endif /* defined(_DOUBLE_IS_32BITS) */
|
||||
70
lib/libm/sf_frexp.c
Normal file
70
lib/libm/sf_frexp.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* sf_frexp.c -- float version of s_frexp.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float
|
||||
#else
|
||||
static float
|
||||
#endif
|
||||
two25 = 3.3554432000e+07; /* 0x4c000000 */
|
||||
|
||||
#ifdef __STDC__
|
||||
float frexpf(float x, int *eptr)
|
||||
#else
|
||||
float frexpf(x, eptr)
|
||||
float x; int *eptr;
|
||||
#endif
|
||||
{
|
||||
__int32_t hx, ix;
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
ix = 0x7fffffff&hx;
|
||||
*eptr = 0;
|
||||
if(!FLT_UWORD_IS_FINITE(ix)||FLT_UWORD_IS_ZERO(ix)) return x; /* 0,inf,nan */
|
||||
if (FLT_UWORD_IS_SUBNORMAL(ix)) { /* subnormal */
|
||||
x *= two25;
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
ix = hx&0x7fffffff;
|
||||
*eptr = -25;
|
||||
}
|
||||
*eptr += (ix>>23)-126;
|
||||
hx = (hx&0x807fffff)|0x3f000000;
|
||||
SET_FLOAT_WORD(x,hx);
|
||||
return x;
|
||||
}
|
||||
|
||||
#ifdef _DOUBLE_IS_32BITS
|
||||
|
||||
#ifdef __STDC__
|
||||
double frexp(double x, int *eptr)
|
||||
#else
|
||||
double frexp(x, eptr)
|
||||
double x; int *eptr;
|
||||
#endif
|
||||
{
|
||||
return (double) frexpf((float) x, eptr);
|
||||
}
|
||||
|
||||
#endif /* defined(_DOUBLE_IS_32BITS) */
|
||||
82
lib/libm/sf_modf.c
Normal file
82
lib/libm/sf_modf.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/common
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* sf_modf.c -- float version of s_modf.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
static const float one = 1.0;
|
||||
#else
|
||||
static float one = 1.0;
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
float modff(float x, float *iptr)
|
||||
#else
|
||||
float modff(x, iptr)
|
||||
float x,*iptr;
|
||||
#endif
|
||||
{
|
||||
__int32_t i0,j0;
|
||||
__uint32_t i;
|
||||
GET_FLOAT_WORD(i0,x);
|
||||
j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */
|
||||
if(j0<23) { /* integer part in x */
|
||||
if(j0<0) { /* |x|<1 */
|
||||
SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */
|
||||
return x;
|
||||
} else {
|
||||
i = (0x007fffff)>>j0;
|
||||
if((i0&i)==0) { /* x is integral */
|
||||
__uint32_t ix;
|
||||
*iptr = x;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
|
||||
return x;
|
||||
} else {
|
||||
SET_FLOAT_WORD(*iptr,i0&(~i));
|
||||
return x - *iptr;
|
||||
}
|
||||
}
|
||||
} else { /* no fraction part */
|
||||
__uint32_t ix;
|
||||
*iptr = x*one;
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DOUBLE_IS_32BITS
|
||||
|
||||
#ifdef __STDC__
|
||||
double modf(double x, double *iptr)
|
||||
#else
|
||||
double modf(x, iptr)
|
||||
double x,*iptr;
|
||||
#endif
|
||||
{
|
||||
return (double) modff((float) x, (float *) iptr);
|
||||
}
|
||||
|
||||
#endif /* defined(_DOUBLE_IS_32BITS) */
|
||||
71
lib/libm/sf_sin.c
Normal file
71
lib/libm/sf_sin.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* sf_sin.c -- float version of s_sin.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
float sinf(float x)
|
||||
#else
|
||||
float sinf(x)
|
||||
float x;
|
||||
#endif
|
||||
{
|
||||
float y[2],z=0.0;
|
||||
__int32_t n,ix;
|
||||
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
|
||||
/* |x| ~< pi/4 */
|
||||
ix &= 0x7fffffff;
|
||||
if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);
|
||||
|
||||
/* sin(Inf or NaN) is NaN */
|
||||
else if (!FLT_UWORD_IS_FINITE(ix)) return x-x;
|
||||
|
||||
/* argument reduction needed */
|
||||
else {
|
||||
n = __ieee754_rem_pio2f(x,y);
|
||||
switch(n&3) {
|
||||
case 0: return __kernel_sinf(y[0],y[1],1);
|
||||
case 1: return __kernel_cosf(y[0],y[1]);
|
||||
case 2: return -__kernel_sinf(y[0],y[1],1);
|
||||
default:
|
||||
return -__kernel_cosf(y[0],y[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DOUBLE_IS_32BITS
|
||||
|
||||
#ifdef __STDC__
|
||||
double sin(double x)
|
||||
#else
|
||||
double sin(x)
|
||||
double x;
|
||||
#endif
|
||||
{
|
||||
return (double) sinf((float) x);
|
||||
}
|
||||
|
||||
#endif /* defined(_DOUBLE_IS_32BITS) */
|
||||
66
lib/libm/sf_tan.c
Normal file
66
lib/libm/sf_tan.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* These math functions are taken from newlib-nano-2, the newlib/libm/math
|
||||
* directory, available from https://github.com/32bitmicro/newlib-nano-2.
|
||||
*
|
||||
* Appropriate copyright headers are reproduced below.
|
||||
*/
|
||||
|
||||
/* sf_tan.c -- float version of s_tan.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
float tanf(float x)
|
||||
#else
|
||||
float tanf(x)
|
||||
float x;
|
||||
#endif
|
||||
{
|
||||
float y[2],z=0.0;
|
||||
__int32_t n,ix;
|
||||
|
||||
GET_FLOAT_WORD(ix,x);
|
||||
|
||||
/* |x| ~< pi/4 */
|
||||
ix &= 0x7fffffff;
|
||||
if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1);
|
||||
|
||||
/* tan(Inf or NaN) is NaN */
|
||||
else if (!FLT_UWORD_IS_FINITE(ix)) return x-x; /* NaN */
|
||||
|
||||
/* argument reduction needed */
|
||||
else {
|
||||
n = __ieee754_rem_pio2f(x,y);
|
||||
return __kernel_tanf(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
|
||||
-1 -- n odd */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DOUBLE_IS_32BITS
|
||||
|
||||
#ifdef __STDC__
|
||||
double tan(double x)
|
||||
#else
|
||||
double tan(x)
|
||||
double x;
|
||||
#endif
|
||||
{
|
||||
return (double) tanf((float) x);
|
||||
}
|
||||
|
||||
#endif /* defined(_DOUBLE_IS_32BITS) */
|
||||
276
lib/mp-readline/readline.c
Normal file
276
lib/mp-readline/readline.c
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "readline.h"
|
||||
#include "pybstdio.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define DEBUG_printf printf
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_printf(...) (void)0
|
||||
#endif
|
||||
|
||||
#define READLINE_HIST_SIZE (MP_ARRAY_SIZE(MP_STATE_PORT(readline_hist)))
|
||||
|
||||
enum { ESEQ_NONE, ESEQ_ESC, ESEQ_ESC_BRACKET, ESEQ_ESC_BRACKET_DIGIT, ESEQ_ESC_O };
|
||||
|
||||
void readline_init0(void) {
|
||||
memset(MP_STATE_PORT(readline_hist), 0, READLINE_HIST_SIZE * sizeof(const char*));
|
||||
}
|
||||
|
||||
STATIC char *str_dup_maybe(const char *str) {
|
||||
uint32_t len = strlen(str);
|
||||
char *s2 = m_new_maybe(char, len + 1);
|
||||
if (s2 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(s2, str, len + 1);
|
||||
return s2;
|
||||
}
|
||||
|
||||
typedef struct _readline_t {
|
||||
vstr_t *line;
|
||||
int orig_line_len;
|
||||
int escape_seq;
|
||||
int hist_cur;
|
||||
int cursor_pos;
|
||||
char escape_seq_buf[1];
|
||||
} readline_t;
|
||||
|
||||
readline_t rl;
|
||||
|
||||
int readline_process_char(int c) {
|
||||
int last_line_len = rl.line->len;
|
||||
int redraw_step_back = 0;
|
||||
bool redraw_from_cursor = false;
|
||||
int redraw_step_forward = 0;
|
||||
if (rl.escape_seq == ESEQ_NONE) {
|
||||
if (CHAR_CTRL_A <= c && c <= CHAR_CTRL_D && vstr_len(rl.line) == rl.orig_line_len) {
|
||||
// control character with empty line
|
||||
return c;
|
||||
} else if (c == CHAR_CTRL_A) {
|
||||
// CTRL-A with non-empty line is go-to-start-of-line
|
||||
goto home_key;
|
||||
} else if (c == CHAR_CTRL_C) {
|
||||
// CTRL-C with non-empty line is cancel
|
||||
return c;
|
||||
} else if (c == CHAR_CTRL_E) {
|
||||
// CTRL-E is go-to-end-of-line
|
||||
goto end_key;
|
||||
} else if (c == '\r') {
|
||||
// newline
|
||||
stdout_tx_str("\r\n");
|
||||
if (rl.line->len > rl.orig_line_len && (MP_STATE_PORT(readline_hist)[0] == NULL || strcmp(MP_STATE_PORT(readline_hist)[0], rl.line->buf + rl.orig_line_len) != 0)) {
|
||||
// a line which is not empty and different from the last one
|
||||
// so update the history
|
||||
char *most_recent_hist = str_dup_maybe(rl.line->buf + rl.orig_line_len);
|
||||
if (most_recent_hist != NULL) {
|
||||
for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) {
|
||||
MP_STATE_PORT(readline_hist)[i] = MP_STATE_PORT(readline_hist)[i - 1];
|
||||
}
|
||||
MP_STATE_PORT(readline_hist)[0] = most_recent_hist;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (c == 27) {
|
||||
// escape sequence
|
||||
rl.escape_seq = ESEQ_ESC;
|
||||
} else if (c == 8 || c == 127) {
|
||||
// backspace/delete
|
||||
if (rl.cursor_pos > rl.orig_line_len) {
|
||||
vstr_cut_out_bytes(rl.line, rl.cursor_pos - 1, 1);
|
||||
// set redraw parameters
|
||||
redraw_step_back = 1;
|
||||
redraw_from_cursor = true;
|
||||
}
|
||||
} else if (32 <= c && c <= 126) {
|
||||
// printable character
|
||||
vstr_ins_char(rl.line, rl.cursor_pos, c);
|
||||
// set redraw parameters
|
||||
redraw_from_cursor = true;
|
||||
redraw_step_forward = 1;
|
||||
}
|
||||
} else if (rl.escape_seq == ESEQ_ESC) {
|
||||
switch (c) {
|
||||
case '[':
|
||||
rl.escape_seq = ESEQ_ESC_BRACKET;
|
||||
break;
|
||||
case 'O':
|
||||
rl.escape_seq = ESEQ_ESC_O;
|
||||
break;
|
||||
default:
|
||||
DEBUG_printf("(ESC %d)", c);
|
||||
rl.escape_seq = ESEQ_NONE;
|
||||
}
|
||||
} else if (rl.escape_seq == ESEQ_ESC_BRACKET) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
rl.escape_seq = ESEQ_ESC_BRACKET_DIGIT;
|
||||
rl.escape_seq_buf[0] = c;
|
||||
} else {
|
||||
rl.escape_seq = ESEQ_NONE;
|
||||
if (c == 'A') {
|
||||
// up arrow
|
||||
if (rl.hist_cur + 1 < READLINE_HIST_SIZE && MP_STATE_PORT(readline_hist)[rl.hist_cur + 1] != NULL) {
|
||||
// increase hist num
|
||||
rl.hist_cur += 1;
|
||||
// set line to history
|
||||
rl.line->len = rl.orig_line_len;
|
||||
vstr_add_str(rl.line, MP_STATE_PORT(readline_hist)[rl.hist_cur]);
|
||||
// set redraw parameters
|
||||
redraw_step_back = rl.cursor_pos - rl.orig_line_len;
|
||||
redraw_from_cursor = true;
|
||||
redraw_step_forward = rl.line->len - rl.orig_line_len;
|
||||
}
|
||||
} else if (c == 'B') {
|
||||
// down arrow
|
||||
if (rl.hist_cur >= 0) {
|
||||
// decrease hist num
|
||||
rl.hist_cur -= 1;
|
||||
// set line to history
|
||||
vstr_cut_tail_bytes(rl.line, rl.line->len - rl.orig_line_len);
|
||||
if (rl.hist_cur >= 0) {
|
||||
vstr_add_str(rl.line, MP_STATE_PORT(readline_hist)[rl.hist_cur]);
|
||||
}
|
||||
// set redraw parameters
|
||||
redraw_step_back = rl.cursor_pos - rl.orig_line_len;
|
||||
redraw_from_cursor = true;
|
||||
redraw_step_forward = rl.line->len - rl.orig_line_len;
|
||||
}
|
||||
} else if (c == 'C') {
|
||||
// right arrow
|
||||
if (rl.cursor_pos < rl.line->len) {
|
||||
redraw_step_forward = 1;
|
||||
}
|
||||
} else if (c == 'D') {
|
||||
// left arrow
|
||||
if (rl.cursor_pos > rl.orig_line_len) {
|
||||
redraw_step_back = 1;
|
||||
}
|
||||
} else if (c == 'H') {
|
||||
// home
|
||||
goto home_key;
|
||||
} else if (c == 'F') {
|
||||
// end
|
||||
goto end_key;
|
||||
} else {
|
||||
DEBUG_printf("(ESC [ %d)", c);
|
||||
}
|
||||
}
|
||||
} else if (rl.escape_seq == ESEQ_ESC_BRACKET_DIGIT) {
|
||||
if (c == '~') {
|
||||
if (rl.escape_seq_buf[0] == '1' || rl.escape_seq_buf[0] == '7') {
|
||||
home_key:
|
||||
redraw_step_back = rl.cursor_pos - rl.orig_line_len;
|
||||
} else if (rl.escape_seq_buf[0] == '4' || rl.escape_seq_buf[0] == '8') {
|
||||
end_key:
|
||||
redraw_step_forward = rl.line->len - rl.cursor_pos;
|
||||
} else {
|
||||
DEBUG_printf("(ESC [ %c %d)", rl.escape_seq_buf[0], c);
|
||||
}
|
||||
} else {
|
||||
DEBUG_printf("(ESC [ %c %d)", rl.escape_seq_buf[0], c);
|
||||
}
|
||||
rl.escape_seq = ESEQ_NONE;
|
||||
} else if (rl.escape_seq == ESEQ_ESC_O) {
|
||||
switch (c) {
|
||||
case 'H':
|
||||
goto home_key;
|
||||
case 'F':
|
||||
goto end_key;
|
||||
default:
|
||||
DEBUG_printf("(ESC O %d)", c);
|
||||
rl.escape_seq = ESEQ_NONE;
|
||||
}
|
||||
} else {
|
||||
rl.escape_seq = ESEQ_NONE;
|
||||
}
|
||||
|
||||
// redraw command prompt, efficiently
|
||||
// TODO we can probably use some more sophisticated VT100 commands here
|
||||
if (redraw_step_back > 0) {
|
||||
for (int i = 0; i < redraw_step_back; i++) {
|
||||
stdout_tx_str("\b");
|
||||
}
|
||||
rl.cursor_pos -= redraw_step_back;
|
||||
}
|
||||
if (redraw_from_cursor) {
|
||||
if (rl.line->len < last_line_len) {
|
||||
// erase old chars
|
||||
for (int i = rl.cursor_pos; i < last_line_len; i++) {
|
||||
stdout_tx_str(" ");
|
||||
}
|
||||
// step back
|
||||
for (int i = rl.cursor_pos; i < last_line_len; i++) {
|
||||
stdout_tx_str("\b");
|
||||
}
|
||||
}
|
||||
// draw new chars
|
||||
stdout_tx_strn(rl.line->buf + rl.cursor_pos, rl.line->len - rl.cursor_pos);
|
||||
// move cursor forward if needed (already moved forward by length of line, so move it back)
|
||||
for (int i = rl.cursor_pos + redraw_step_forward; i < rl.line->len; i++) {
|
||||
stdout_tx_str("\b");
|
||||
}
|
||||
rl.cursor_pos += redraw_step_forward;
|
||||
} else if (redraw_step_forward > 0) {
|
||||
// draw over old chars to move cursor forwards
|
||||
stdout_tx_strn(rl.line->buf + rl.cursor_pos, redraw_step_forward);
|
||||
rl.cursor_pos += redraw_step_forward;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void readline_note_newline(void) {
|
||||
rl.orig_line_len = rl.line->len;
|
||||
rl.cursor_pos = rl.orig_line_len;
|
||||
}
|
||||
|
||||
void readline_init(vstr_t *line) {
|
||||
rl.line = line;
|
||||
rl.orig_line_len = line->len;
|
||||
rl.escape_seq = ESEQ_NONE;
|
||||
rl.escape_seq_buf[0] = 0;
|
||||
rl.hist_cur = -1;
|
||||
rl.cursor_pos = rl.orig_line_len;
|
||||
}
|
||||
|
||||
int readline(vstr_t *line, const char *prompt) {
|
||||
stdout_tx_str(prompt);
|
||||
readline_init(line);
|
||||
for (;;) {
|
||||
int c = stdin_rx_chr();
|
||||
int r = readline_process_char(c);
|
||||
if (r >= 0) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,3 +32,7 @@
|
||||
|
||||
void readline_init0(void);
|
||||
int readline(vstr_t *line, const char *prompt);
|
||||
|
||||
void readline_init(vstr_t *line);
|
||||
void readline_note_newline(void);
|
||||
int readline_process_char(int c);
|
||||
77
minimal/Makefile
Normal file
77
minimal/Makefile
Normal file
@@ -0,0 +1,77 @@
|
||||
include ../py/mkenv.mk
|
||||
|
||||
CROSS = 0
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
||||
ifeq ($(CROSS), 1)
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
endif
|
||||
|
||||
INC = -I.
|
||||
INC += -I..
|
||||
INC += -I../lib/mp-readline
|
||||
INC += -I../stmhal
|
||||
INC += -I$(BUILD)
|
||||
|
||||
ifeq ($(CROSS), 1)
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
|
||||
else
|
||||
CFLAGS = -m32 $(INC) -Wall -Werror -ansi -std=gnu99 $(COPT)
|
||||
endif
|
||||
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -ggdb
|
||||
else
|
||||
CFLAGS += -Os -DNDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(CROSS), 1)
|
||||
LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref
|
||||
else
|
||||
LD = gcc
|
||||
LDFLAGS = -m32 -Wl,-Map=$@.map,--cref
|
||||
endif
|
||||
LIBS =
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
uart_core.c \
|
||||
uart_extra.c \
|
||||
stmhal/printf.c \
|
||||
stmhal/string0.c \
|
||||
stmhal/pyexec.c \
|
||||
lib/mp-readline/readline.c \
|
||||
|
||||
SRC_S = \
|
||||
# startup_stm32f40xx.s \
|
||||
gchelper.s \
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o))
|
||||
|
||||
all: $(BUILD)/firmware.elf
|
||||
|
||||
$(BUILD)/firmware.elf: $(OBJ)
|
||||
$(ECHO) "LINK $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
|
||||
$(Q)$(SIZE) $@
|
||||
|
||||
# Run emulation build on a POSIX system with suitable terminal settings
|
||||
run:
|
||||
stty raw opost -echo
|
||||
build/firmware.elf
|
||||
@echo Resetting terminal...
|
||||
# This sleep is useful to spot segfaults
|
||||
sleep 1
|
||||
reset
|
||||
|
||||
test: $(BUILD)/firmware.elf
|
||||
$(Q)/bin/echo -e "print('hello world!', list(x+1 for x in range(10)), end='eol\\\\n')\\r\\n\\x04" | $(BUILD)/firmware.elf | tail -n2 | grep "^hello world! \\[1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\]eol"
|
||||
|
||||
include ../py/mkrules.mk
|
||||
118
minimal/main.c
Normal file
118
minimal/main.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/parsehelper.h"
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/pfenv.h"
|
||||
#include "py/gc.h"
|
||||
#include "pyexec.h"
|
||||
#include "pybstdio.h"
|
||||
|
||||
void do_str(const char *src) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mp_parse_error_kind_t parse_error_kind;
|
||||
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind);
|
||||
|
||||
if (pn == MP_PARSE_NODE_NULL) {
|
||||
// parse error
|
||||
mp_parse_show_exception(lex, parse_error_kind);
|
||||
mp_lexer_free(lex);
|
||||
return;
|
||||
}
|
||||
|
||||
// parse okay
|
||||
qstr source_name = lex->source_name;
|
||||
mp_lexer_free(lex);
|
||||
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
|
||||
|
||||
if (mp_obj_is_exception_instance(module_fun)) {
|
||||
// compile error
|
||||
mp_obj_print_exception(printf_wrapper, NULL, module_fun);
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_call_function_0(module_fun);
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception
|
||||
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
static char *stack_top;
|
||||
static char heap[2048];
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int stack_dummy;
|
||||
stack_top = (char*)&stack_dummy;
|
||||
|
||||
#if MICROPY_ENABLE_GC
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
#endif
|
||||
mp_init();
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
pyexec_friendly_repl_init();
|
||||
for (;;) {
|
||||
int c = stdin_rx_chr();
|
||||
if (pyexec_friendly_repl_process_char(c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
pyexec_friendly_repl();
|
||||
#endif
|
||||
//do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')");
|
||||
mp_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
// WARNING: This gc_collect implementation doesn't try to get root
|
||||
// pointers from CPU registers, and thus may function incorrectly.
|
||||
void *dummy;
|
||||
gc_collect_start();
|
||||
gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
|
||||
gc_collect_end();
|
||||
gc_dump_info();
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
|
||||
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
|
||||
__fatal_error("Assertion failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !MICROPY_MIN_USE_STDOUT
|
||||
void _start(void) {main(0, NULL);}
|
||||
#endif
|
||||
81
minimal/mpconfigport.h
Normal file
81
minimal/mpconfigport.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_ALLOC_PATH_MAX (256)
|
||||
#define MICROPY_EMIT_X64 (0)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_COMP_MODULE_CONST (0)
|
||||
#define MICROPY_COMP_CONST (0)
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_REPL_EVENT_DRIVEN (0)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||
#define MICROPY_ENABLE_DOC_STRING (0)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (0)
|
||||
#define MICROPY_PY_BUILTINS_SET (0)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (0)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (0)
|
||||
#define MICROPY_PY___FILE__ (0)
|
||||
#define MICROPY_PY_GC (0)
|
||||
#define MICROPY_PY_ARRAY (0)
|
||||
#define MICROPY_PY_COLLECTIONS (0)
|
||||
#define MICROPY_PY_MATH (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (0)
|
||||
#define MICROPY_PY_STRUCT (0)
|
||||
#define MICROPY_PY_SYS (0)
|
||||
#define MICROPY_MODULE_FROZEN (0)
|
||||
#define MICROPY_CPYTHON_COMPAT (0)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define BYTES_PER_WORD (4)
|
||||
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
||||
|
||||
// This port is intended to be 32-bit, but unfortunately, int32_t for
|
||||
// different targets may be defined in different ways - either as int
|
||||
// or as long. This requires different printf formatting specifiers
|
||||
// to print such value. So, we avoid int32_t and use int directly.
|
||||
#define UINT_FMT "%u"
|
||||
#define INT_FMT "%d"
|
||||
typedef int mp_int_t; // must be pointer size
|
||||
typedef unsigned mp_uint_t; // must be pointer size
|
||||
|
||||
typedef void *machine_ptr_t; // must be of pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||
typedef long mp_off_t;
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#include <alloca.h>
|
||||
|
||||
#define HAL_GetTick() 0
|
||||
|
||||
static inline void mp_hal_set_interrupt_char(char c) {}
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "minimal"
|
||||
#define MICROPY_HW_MCU_NAME "unknown-cpu"
|
||||
|
||||
#ifdef __linux__
|
||||
#define MICROPY_MIN_USE_STDOUT (1)
|
||||
#endif
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
const char *readline_hist[8];
|
||||
1
minimal/qstrdefsport.h
Normal file
1
minimal/qstrdefsport.h
Normal file
@@ -0,0 +1 @@
|
||||
// qstrs specific to this port
|
||||
117
minimal/stm32f405.ld
Normal file
117
minimal/stm32f405.ld
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
GNU linker script for STM32F405
|
||||
*/
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
|
||||
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 0x004000 /* sector 0, 16 KiB */
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x080000 /* sectors 5,6,7,8, 4*128KiB = 512 KiB (could increase it more) */
|
||||
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
|
||||
}
|
||||
|
||||
/* top end of the stack */
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
|
||||
/* RAM extents for the garbage collector */
|
||||
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_heap_end = 0x2001c000; /* tunable */
|
||||
|
||||
/* define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
|
||||
. = ALIGN(4);
|
||||
} >FLASH_ISR
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
/* *(.glue_7) */ /* glue arm to thumb code */
|
||||
/* *(.glue_7t) */ /* glue thumb to arm code */
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbol at end of code */
|
||||
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
|
||||
} >FLASH_TEXT
|
||||
|
||||
/*
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >FLASH
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
*/
|
||||
|
||||
/* This is the initialized data section
|
||||
The program executes knowing that the data is in the RAM
|
||||
but the loader puts the initial values in the FLASH (inidata).
|
||||
It is one task of the startup to copy the initial values from FLASH to RAM. */
|
||||
.data : AT ( _sidata )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
|
||||
_ram_start = .; /* create a global symbol at ram start for garbage collector */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
|
||||
} >RAM
|
||||
|
||||
/* Uninitialized data section */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .; /* define a global symbol at bss start; used by startup code */
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end; used by startup code */
|
||||
} >RAM
|
||||
|
||||
/* this is to define the start of the heap, and make sure we have a minimum size */
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_heap_start = .; /* define a global symbol at heap start */
|
||||
} >RAM
|
||||
|
||||
/* this just checks there is enough RAM for the stack */
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* Remove information from the standard libraries */
|
||||
/*
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a ( * )
|
||||
libm.a ( * )
|
||||
libgcc.a ( * )
|
||||
}
|
||||
*/
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
24
minimal/uart_core.c
Normal file
24
minimal/uart_core.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <unistd.h>
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
/*
|
||||
* Core UART functions to implement for a port
|
||||
*/
|
||||
|
||||
// Receive single character
|
||||
int stdin_rx_chr(void) {
|
||||
unsigned char c = 0;
|
||||
#if MICROPY_MIN_USE_STDOUT
|
||||
int r = read(0, &c, 1);
|
||||
(void)r;
|
||||
#endif
|
||||
return c;
|
||||
}
|
||||
|
||||
// Send string of given length
|
||||
void stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
#if MICROPY_MIN_USE_STDOUT
|
||||
int r = write(1, str, len);
|
||||
(void)r;
|
||||
#endif
|
||||
}
|
||||
26
minimal/uart_extra.c
Normal file
26
minimal/uart_extra.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "py/mpconfig.h"
|
||||
#include "pybstdio.h"
|
||||
|
||||
/*
|
||||
* Extra UART functions
|
||||
* These can be either optimized for a particular port, or reference,
|
||||
* not very optimal implementation below can be used.
|
||||
*/
|
||||
|
||||
// Send "cooked" string of length, where every occurance of
|
||||
// LF character is replaced with CR LF.
|
||||
void stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
while (len--) {
|
||||
if (*str == '\n') {
|
||||
stdout_tx_strn("\r", 1);
|
||||
}
|
||||
stdout_tx_strn(str++, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Send zero-terminated string
|
||||
void stdout_tx_str(const char *str) {
|
||||
stdout_tx_strn(str, strlen(str));
|
||||
}
|
||||
@@ -27,23 +27,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
STATIC NORETURN void terse_arg_mismatch(void) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "argument num/types mismatch"));
|
||||
}
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp_uint_t n_args_max, bool takes_kw) {
|
||||
// TODO maybe take the function name as an argument so we can print nicer error messages
|
||||
|
||||
if (n_kw && !takes_kw) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
terse_arg_mismatch();
|
||||
mp_arg_error_terse_mismatch();
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
|
||||
"function does not take keyword arguments"));
|
||||
@@ -53,7 +45,7 @@ void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp
|
||||
if (n_args_min == n_args_max) {
|
||||
if (n_args != n_args_min) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
terse_arg_mismatch();
|
||||
mp_arg_error_terse_mismatch();
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"function takes %d positional arguments but %d were given",
|
||||
@@ -63,7 +55,7 @@ void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp
|
||||
} else {
|
||||
if (n_args < n_args_min) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
terse_arg_mismatch();
|
||||
mp_arg_error_terse_mismatch();
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"function missing %d required positional arguments",
|
||||
@@ -71,7 +63,7 @@ void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp
|
||||
}
|
||||
} else if (n_args > n_args_max) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
terse_arg_mismatch();
|
||||
mp_arg_error_terse_mismatch();
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"function expected at most %d arguments, got %d",
|
||||
@@ -92,15 +84,15 @@ void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_ui
|
||||
pos_found++;
|
||||
given_arg = pos[i];
|
||||
} else {
|
||||
mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qstr), MP_MAP_LOOKUP);
|
||||
mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qst), MP_MAP_LOOKUP);
|
||||
if (kw == NULL) {
|
||||
if (allowed[i].flags & MP_ARG_REQUIRED) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
terse_arg_mismatch();
|
||||
mp_arg_error_terse_mismatch();
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' argument required",
|
||||
qstr_str(allowed[i].qstr)));
|
||||
qstr_str(allowed[i].qst)));
|
||||
}
|
||||
}
|
||||
out_vals[i] = allowed[i].defval;
|
||||
@@ -123,7 +115,7 @@ void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_ui
|
||||
if (pos_found < n_pos) {
|
||||
extra_positional:
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
terse_arg_mismatch();
|
||||
mp_arg_error_terse_mismatch();
|
||||
} else {
|
||||
// TODO better error message
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
|
||||
@@ -132,7 +124,7 @@ void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_ui
|
||||
}
|
||||
if (kws_found < kws->used) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
terse_arg_mismatch();
|
||||
mp_arg_error_terse_mismatch();
|
||||
} else {
|
||||
// TODO better error message
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
|
||||
@@ -147,6 +139,12 @@ void mp_arg_parse_all_kw_array(mp_uint_t n_pos, mp_uint_t n_kw, const mp_obj_t *
|
||||
mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals);
|
||||
}
|
||||
|
||||
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || _MSC_VER
|
||||
NORETURN void mp_arg_error_terse_mismatch(void) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "argument num/types mismatch"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
NORETURN void mp_arg_error_unimpl_kw(void) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
|
||||
|
||||
27
py/asmarm.c
27
py/asmarm.c
@@ -29,13 +29,13 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "asmarm.h"
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
// wrapper around everything in this file
|
||||
#if MICROPY_EMIT_ARM
|
||||
|
||||
#include "py/asmarm.h"
|
||||
|
||||
#define SIGNED_FIT24(x) (((x) & 0xff800000) == 0) || (((x) & 0xff000000) == 0xff000000)
|
||||
|
||||
struct _asm_arm_t {
|
||||
@@ -70,20 +70,20 @@ void asm_arm_free(asm_arm_t *as, bool free_code) {
|
||||
}
|
||||
|
||||
void asm_arm_start_pass(asm_arm_t *as, uint pass) {
|
||||
as->pass = pass;
|
||||
as->code_offset = 0;
|
||||
if (pass == ASM_ARM_PASS_COMPUTE) {
|
||||
memset(as->label_offsets, -1, as->max_num_labels * sizeof(mp_uint_t));
|
||||
} else if (pass == ASM_ARM_PASS_EMIT) {
|
||||
MP_PLAT_ALLOC_EXEC(as->code_offset, (void**)&as->code_base, &as->code_size);
|
||||
if (as->code_base == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
as->pass = pass;
|
||||
as->code_offset = 0;
|
||||
}
|
||||
|
||||
void asm_arm_end_pass(asm_arm_t *as) {
|
||||
if (as->pass == ASM_ARM_PASS_COMPUTE) {
|
||||
MP_PLAT_ALLOC_EXEC(as->code_offset, (void**) &as->code_base, &as->code_size);
|
||||
if(as->code_base == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
} else if(as->pass == ASM_ARM_PASS_EMIT) {
|
||||
if (as->pass == ASM_ARM_PASS_EMIT) {
|
||||
#ifdef __arm__
|
||||
// flush I- and D-cache
|
||||
asm volatile(
|
||||
@@ -282,8 +282,9 @@ void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) {
|
||||
// TODO: There are more variants of immediate values
|
||||
if ((imm & 0xFF) == imm) {
|
||||
emit_al(as, asm_arm_op_mov_imm(rd, imm));
|
||||
} else if (imm < 0 && ((-imm) & 0xFF) == -imm) {
|
||||
emit_al(as, asm_arm_op_mvn_imm(rd, -imm));
|
||||
} else if (imm < 0 && imm >= -256) {
|
||||
// mvn is "move not", not "move negative"
|
||||
emit_al(as, asm_arm_op_mvn_imm(rd, ~imm));
|
||||
} else {
|
||||
//Insert immediate into code and jump over it
|
||||
emit_al(as, 0x59f0000 | (rd << 12)); // ldr rd, [pc]
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __MICROPY_INCLUDED_PY_ASMARM_H__
|
||||
#define __MICROPY_INCLUDED_PY_ASMARM_H__
|
||||
|
||||
#include "py/misc.h"
|
||||
|
||||
#define ASM_ARM_PASS_COMPUTE (1)
|
||||
#define ASM_ARM_PASS_EMIT (2)
|
||||
@@ -120,3 +124,4 @@ void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label);
|
||||
void asm_arm_b_label(asm_arm_t *as, uint label);
|
||||
void asm_arm_bl_ind(asm_arm_t *as, void *fun_ptr, uint fun_id, uint reg_temp);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_PY_ASMARM_H__
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "asmthumb.h"
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
// wrapper around everything in this file
|
||||
#if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB
|
||||
|
||||
#include "py/asmthumb.h"
|
||||
|
||||
#define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0)
|
||||
#define UNSIGNED_FIT16(x) (((x) & 0xffff0000) == 0)
|
||||
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
|
||||
@@ -73,32 +73,21 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) {
|
||||
}
|
||||
|
||||
void asm_thumb_start_pass(asm_thumb_t *as, uint pass) {
|
||||
as->pass = pass;
|
||||
as->code_offset = 0;
|
||||
if (pass == ASM_THUMB_PASS_COMPUTE) {
|
||||
memset(as->label_offsets, -1, as->max_num_labels * sizeof(mp_uint_t));
|
||||
}
|
||||
}
|
||||
|
||||
void asm_thumb_end_pass(asm_thumb_t *as) {
|
||||
if (as->pass == ASM_THUMB_PASS_COMPUTE) {
|
||||
MP_PLAT_ALLOC_EXEC(as->code_offset, (void**) &as->code_base, &as->code_size);
|
||||
if(as->code_base == NULL) {
|
||||
} else if (pass == ASM_THUMB_PASS_EMIT) {
|
||||
MP_PLAT_ALLOC_EXEC(as->code_offset, (void**)&as->code_base, &as->code_size);
|
||||
if (as->code_base == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
//printf("code_size: %u\n", as->code_size);
|
||||
}
|
||||
as->pass = pass;
|
||||
as->code_offset = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
// check labels are resolved
|
||||
if (as->label != NULL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < as->label->len; ++i)
|
||||
if (g_array_index(as->label, Label, i).unresolved != NULL)
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
void asm_thumb_end_pass(asm_thumb_t *as) {
|
||||
// could check labels are resolved...
|
||||
}
|
||||
|
||||
// all functions must go through this one to emit bytes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user