mirror of
https://github.com/micropython/micropython.git
synced 2025-12-28 15:50:14 +01:00
Compare commits
252 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3611dcc260 | ||
|
|
763e04bba5 | ||
|
|
f3b5480be7 | ||
|
|
dab0f316d2 | ||
|
|
742d8bdbe4 | ||
|
|
b4be5a8f34 | ||
|
|
4a9542c0c0 | ||
|
|
9103cbe366 | ||
|
|
b88bf6c76b | ||
|
|
69768c97c0 | ||
|
|
e4d6a10dc9 | ||
|
|
2b882e9aca | ||
|
|
ef47a67cf4 | ||
|
|
9526e24234 | ||
|
|
e2ac8bb3f1 | ||
|
|
cac8dc3414 | ||
|
|
778729c597 | ||
|
|
b4df3e74e1 | ||
|
|
20da9064d7 | ||
|
|
dba40afa70 | ||
|
|
7ddd1a58f6 | ||
|
|
1708fe3cc7 | ||
|
|
61e2dfd97d | ||
|
|
1bc5cb4312 | ||
|
|
fedab995ee | ||
|
|
2d8740a4d1 | ||
|
|
47899a1ab8 | ||
|
|
8c6856d2e7 | ||
|
|
015774a04f | ||
|
|
4a33677c97 | ||
|
|
76c366df56 | ||
|
|
f7c4611523 | ||
|
|
fafd587514 | ||
|
|
a6864a13c7 | ||
|
|
c51c883cc8 | ||
|
|
41ec22632d | ||
|
|
b6bdf18deb | ||
|
|
b4790afdaf | ||
|
|
58f3861358 | ||
|
|
5f3bda422a | ||
|
|
f127bef3e4 | ||
|
|
f98bb2ddcb | ||
|
|
ce1c786297 | ||
|
|
49406b0ac6 | ||
|
|
9b64d1966b | ||
|
|
3be8b688c0 | ||
|
|
5863e15a23 | ||
|
|
0823c1baf8 | ||
|
|
9c04ef2a67 | ||
|
|
1f61fe07a2 | ||
|
|
bae62d9abe | ||
|
|
76dcaddc0f | ||
|
|
efc904c41d | ||
|
|
5c3a2f162e | ||
|
|
d1a366fdd4 | ||
|
|
c777b6950e | ||
|
|
0f8b1ba8a2 | ||
|
|
f2da6467a9 | ||
|
|
57c92d90b0 | ||
|
|
13c5a228c9 | ||
|
|
59a9509703 | ||
|
|
8e9b98e974 | ||
|
|
9fba618356 | ||
|
|
ed0a06a93f | ||
|
|
263aaa7030 | ||
|
|
8f8f699eb7 | ||
|
|
f4ee9f8853 | ||
|
|
581a59a456 | ||
|
|
531217a06b | ||
|
|
fea7fe45ea | ||
|
|
26295e04ff | ||
|
|
fe3cc5bb53 | ||
|
|
3b5affa0d1 | ||
|
|
24df30c133 | ||
|
|
fc73c9b4b2 | ||
|
|
5ffe1d8dc0 | ||
|
|
d29ca28288 | ||
|
|
b0e2106fb8 | ||
|
|
891479e62a | ||
|
|
9897bcaa73 | ||
|
|
a589fa3e0b | ||
|
|
d09b6b9aa1 | ||
|
|
78bc31e294 | ||
|
|
5af6184e72 | ||
|
|
c428367543 | ||
|
|
39799f7564 | ||
|
|
6562076454 | ||
|
|
5a5449d4eb | ||
|
|
253e1a6f67 | ||
|
|
d2d9dfcd40 | ||
|
|
c6983e3ce0 | ||
|
|
f2a21a2489 | ||
|
|
d076fae219 | ||
|
|
8e7dfea803 | ||
|
|
49dd532180 | ||
|
|
64c5a9435c | ||
|
|
567e7fcd12 | ||
|
|
244332df9f | ||
|
|
a6fc90f92a | ||
|
|
ed4ce196ed | ||
|
|
ff1c2b03a9 | ||
|
|
bb19e7b94b | ||
|
|
f003310dee | ||
|
|
ed6a1ada24 | ||
|
|
d2cc7c720b | ||
|
|
095e43a9a5 | ||
|
|
f6a8e84a25 | ||
|
|
675d1c9c60 | ||
|
|
41fceae559 | ||
|
|
b359cf2911 | ||
|
|
d5f42c9daf | ||
|
|
3c82d1d34b | ||
|
|
2196799051 | ||
|
|
1a0d3fd632 | ||
|
|
4aaa5adf9f | ||
|
|
9cf2949356 | ||
|
|
0be4a7712d | ||
|
|
c4a8004933 | ||
|
|
83e0ebabb4 | ||
|
|
8c50f93a41 | ||
|
|
9e1b61dedd | ||
|
|
af9889f99a | ||
|
|
dfb8144037 | ||
|
|
4e36dd570b | ||
|
|
5e01fb01b3 | ||
|
|
72ae3c72c7 | ||
|
|
8a15e0b1c7 | ||
|
|
b203c1774e | ||
|
|
2146cdab5e | ||
|
|
e4e4526954 | ||
|
|
3c9510d767 | ||
|
|
3372f69586 | ||
|
|
6d11918d49 | ||
|
|
5c73de0337 | ||
|
|
3e5534caf7 | ||
|
|
1bc2911174 | ||
|
|
d2cab0b7be | ||
|
|
8897dcb2a1 | ||
|
|
f84dda7111 | ||
|
|
a9923d190e | ||
|
|
919c54f750 | ||
|
|
1966745689 | ||
|
|
31ad1bb606 | ||
|
|
541e76fa45 | ||
|
|
f71f37e426 | ||
|
|
c2070d771a | ||
|
|
1563388001 | ||
|
|
56eb25f049 | ||
|
|
a4aaf82421 | ||
|
|
fdb411a8c5 | ||
|
|
8a0b6f561c | ||
|
|
e15fb33e10 | ||
|
|
cbef0dba2e | ||
|
|
e0d49b7e1b | ||
|
|
6de37864a2 | ||
|
|
ca59f5f208 | ||
|
|
5b9e7e29f6 | ||
|
|
a931c4eeec | ||
|
|
3d19adf9b3 | ||
|
|
d79342d33e | ||
|
|
ed500e4987 | ||
|
|
c16612ee87 | ||
|
|
7fb31479bf | ||
|
|
b67eb20ed0 | ||
|
|
4a27ad040e | ||
|
|
e33d2383d1 | ||
|
|
bf47b71b78 | ||
|
|
a621333a4c | ||
|
|
efb8aa0ef6 | ||
|
|
ce166e6b68 | ||
|
|
3eb532e974 | ||
|
|
8766bc02dc | ||
|
|
b4564841b6 | ||
|
|
0e4cae5212 | ||
|
|
88d3cd582e | ||
|
|
bc3912980a | ||
|
|
eb0e3bab1e | ||
|
|
4d22ade102 | ||
|
|
64ad838fde | ||
|
|
617bda27e9 | ||
|
|
aac9e8cfa3 | ||
|
|
99061d1dcb | ||
|
|
0dfe849413 | ||
|
|
2ec943284a | ||
|
|
460bceca39 | ||
|
|
afd4909a0f | ||
|
|
37b143ce9e | ||
|
|
61e77a4e88 | ||
|
|
58d9d85a56 | ||
|
|
ba2c503541 | ||
|
|
50fea19416 | ||
|
|
c8b80e4740 | ||
|
|
4f1b0292db | ||
|
|
abd5a57ea1 | ||
|
|
3990b1715d | ||
|
|
f039ac5bd7 | ||
|
|
64da62ec2e | ||
|
|
aa4ada943a | ||
|
|
01816068c8 | ||
|
|
a60b0263ba | ||
|
|
ade36806c8 | ||
|
|
8fac939889 | ||
|
|
6ead9f6f3d | ||
|
|
f2f761c0c3 | ||
|
|
243f8988be | ||
|
|
d1771bbae0 | ||
|
|
ed1c194ebf | ||
|
|
6af90b2972 | ||
|
|
16f324641f | ||
|
|
1a7e28d8b7 | ||
|
|
5a38694f55 | ||
|
|
25df419c67 | ||
|
|
0d221775f5 | ||
|
|
2dd21d9a68 | ||
|
|
614deb82c7 | ||
|
|
a53e0e59f3 | ||
|
|
c141584e1e | ||
|
|
77f0cd8027 | ||
|
|
4d4cfc2ee6 | ||
|
|
1e77e25675 | ||
|
|
e47c2ec64a | ||
|
|
9bdb82ef6b | ||
|
|
43473372e6 | ||
|
|
b652ee705b | ||
|
|
40214b9e26 | ||
|
|
918851e836 | ||
|
|
a1b442bc07 | ||
|
|
707cae7494 | ||
|
|
26b7d8a7be | ||
|
|
43963a8d97 | ||
|
|
68815901d4 | ||
|
|
93e353e384 | ||
|
|
04c27e5eaa | ||
|
|
c3f519adfe | ||
|
|
bd6622abe8 | ||
|
|
6aa7c805cc | ||
|
|
bcd0e9a7fa | ||
|
|
0a6f599cf2 | ||
|
|
780114e398 | ||
|
|
0b52228739 | ||
|
|
ad9b9c7621 | ||
|
|
be313ea215 | ||
|
|
20283aec10 | ||
|
|
e32d1e17bb | ||
|
|
dfe056df6f | ||
|
|
ee622cc1ed | ||
|
|
26d5e91bf3 | ||
|
|
3593d8e10c | ||
|
|
e9f3fb7662 | ||
|
|
9626662819 | ||
|
|
7711d87563 | ||
|
|
e3f0f31e07 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,6 +32,7 @@ tests/*.out
|
||||
# Python cache files
|
||||
######################
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Customized Makefile/project overrides
|
||||
######################
|
||||
|
||||
@@ -23,6 +23,7 @@ before_script:
|
||||
- python3 --version
|
||||
|
||||
script:
|
||||
- make -C mpy-cross
|
||||
- make -C minimal test
|
||||
- make -C unix deplibs
|
||||
- make -C unix
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#define MICROPY_CPYTHON_COMPAT (0)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
#define MICROPY_USE_INTERNAL_PRINTF (0)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
@@ -54,8 +55,6 @@
|
||||
|
||||
typedef int32_t mp_int_t; // must be pointer size
|
||||
typedef uint32_t 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;
|
||||
|
||||
// dummy print
|
||||
|
||||
@@ -154,7 +154,6 @@ APP_LIB_SRC_C = $(addprefix lib/,\
|
||||
timeutils/timeutils.c \
|
||||
utils/pyexec.c \
|
||||
utils/pyhelp.c \
|
||||
utils/printf.c \
|
||||
)
|
||||
|
||||
APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
|
||||
@@ -198,7 +198,8 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IDLE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) }, // legacy constant
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PWRON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HARD_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WDT_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) },
|
||||
|
||||
@@ -185,8 +185,6 @@ extern const struct _mp_obj_module_t mp_module_ussl;
|
||||
|
||||
typedef int32_t mp_int_t; // must be pointer size
|
||||
typedef unsigned int 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;
|
||||
|
||||
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
|
||||
@@ -198,14 +196,6 @@ typedef long mp_off_t;
|
||||
// disabling/enabling and sleep mode enter/exit
|
||||
#include "cc3200_asm.h"
|
||||
|
||||
// There is no classical C heap in bare-metal ports, only Python
|
||||
// garbage-collected heap. For completeness, emulate C heap via
|
||||
// GC heap. Note that MicroPython core never uses malloc() and friends,
|
||||
// so these defines are mostly to help extension module writers.
|
||||
#define malloc gc_alloc
|
||||
#define free gc_free
|
||||
#define realloc gc_realloc
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#include <alloca.h>
|
||||
|
||||
|
||||
@@ -35,6 +35,6 @@ This can be achieved with:
|
||||
make MICROPY_PORT=<port_name> latexpdf
|
||||
|
||||
but require rather complete install of LaTeX with various extensions. On
|
||||
Debiab/Ubuntu, try (500MB+ download):
|
||||
Debian/Ubuntu, try (500MB+ download):
|
||||
|
||||
apt-get install texlive-latex-recommended texlive-latex-extra
|
||||
|
||||
@@ -99,7 +99,7 @@ copyright = '2014-2016, Damien P. George and contributors'
|
||||
# The short X.Y version.
|
||||
version = '1.8'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.8.2'
|
||||
release = '1.8.4'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -52,7 +52,7 @@ For your convenience, some of technical specifications are provided below:
|
||||
external FlashROM, UART, deep sleep wake-up, etc.)
|
||||
* UART: One RX/TX UART (no hardware handshaking), one TX-only UART.
|
||||
* SPI: 2 SPI interfaces (one used for FlashROM).
|
||||
* I2C: No native extenal I2C (bitbang implementation available on any pins).
|
||||
* I2C: No native external I2C (bitbang implementation available on any pins).
|
||||
* I2S: 1.
|
||||
* Programming: using BootROM bootloader from UART. Due to external FlashROM
|
||||
and always-available BootROM bootloader, ESP8266 is not brickable.
|
||||
|
||||
@@ -9,6 +9,12 @@ Quick reference for the ESP8266
|
||||
|
||||
The Adafruit Feather HUZZAH board (image attribution: Adafruit).
|
||||
|
||||
Installing MicroPython
|
||||
----------------------
|
||||
|
||||
See the corresponding section of tutorial: :ref:`intro`. It also includes
|
||||
a troubleshooting subsection.
|
||||
|
||||
General board control
|
||||
---------------------
|
||||
|
||||
@@ -17,14 +23,14 @@ Tab-completion is useful to find out what methods an object has.
|
||||
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
|
||||
the REPL.
|
||||
|
||||
The ``machine`` module::
|
||||
The :mod:`machine` module::
|
||||
|
||||
import machine
|
||||
|
||||
machine.freq() # get the current frequency of the CPU
|
||||
machine.freq(160000000) # set the CPU frequency to 160 MHz
|
||||
|
||||
The ``esp`` module::
|
||||
The :mod:`esp` module::
|
||||
|
||||
import esp
|
||||
|
||||
@@ -34,7 +40,7 @@ The ``esp`` module::
|
||||
Networking
|
||||
----------
|
||||
|
||||
The ``network`` module::
|
||||
The :mod:`network` module::
|
||||
|
||||
import network
|
||||
|
||||
@@ -63,13 +69,13 @@ A useful function for connecting to your local WiFi network is::
|
||||
pass
|
||||
print('network config:', wlan.ifconfig())
|
||||
|
||||
Once the network is established the ``socket`` module can be used
|
||||
Once the network is established the :mod:`socket <usocket>` module can be used
|
||||
to create and use TCP/UDP sockets as usual.
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
Use the ``time`` module::
|
||||
Use the :mod:`time <utime>` module::
|
||||
|
||||
import time
|
||||
|
||||
@@ -156,17 +162,18 @@ Use the ``machine.ADC`` class::
|
||||
adc = ADC(0) # create ADC object on ADC pin
|
||||
adc.read() # read value, 0-1024
|
||||
|
||||
SPI bus
|
||||
-------
|
||||
Software SPI bus
|
||||
----------------
|
||||
|
||||
The SPI driver is implemented in software and works on all pins::
|
||||
There are two SPI drivers. One is implemented in software (bit-banging)
|
||||
and works on all pins::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
# construct an SPI bus on the given pins
|
||||
# polarity is the idle state of SCK
|
||||
# phase=0 means sample on the first edge of SCK, phase=1 means the second
|
||||
spi = SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
||||
spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
||||
|
||||
spi.init(baudrate=200000) # set the baudrate
|
||||
|
||||
@@ -183,6 +190,21 @@ The SPI driver is implemented in software and works on all pins::
|
||||
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
|
||||
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
|
||||
|
||||
|
||||
Hardware SPI bus
|
||||
----------------
|
||||
|
||||
The hardware SPI is faster (up to 80Mhz), but only works on following pins:
|
||||
``MISO`` is GPIO12, ``MOSI`` is GPIO13, and ``SCK`` is GPIO14. It has the same
|
||||
methods as the bitbanging SPI class above, except for the pin parameters for the
|
||||
constructor and init (as those are fixed)::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)
|
||||
|
||||
(``SPI(0)`` is used for FlashROM and not available to users.)
|
||||
|
||||
I2C bus
|
||||
-------
|
||||
|
||||
@@ -233,15 +255,14 @@ The OneWire driver is implemented in software and works on all pins::
|
||||
ow.scan() # return a list of devices on the bus
|
||||
ow.reset() # reset the bus
|
||||
ow.readbyte() # read a byte
|
||||
ow.read(5) # read 5 bytes
|
||||
ow.writebyte(0x12) # write a byte on the bus
|
||||
ow.write('123') # write bytes on the bus
|
||||
ow.select_rom(b'12345678') # select a specific device by its ROM code
|
||||
|
||||
There is a specific driver for DS18B20 devices::
|
||||
There is a specific driver for DS18S20 and DS18B20 devices::
|
||||
|
||||
import time
|
||||
ds = onewire.DS18B20(ow)
|
||||
import time, ds18x20
|
||||
ds = ds18x20.DS18X20(ow)
|
||||
roms = ds.scan()
|
||||
ds.convert_temp()
|
||||
time.sleep_ms(750)
|
||||
@@ -291,6 +312,24 @@ For low-level driving of an APA102::
|
||||
import esp
|
||||
esp.apa102_write(clock_pin, data_pin, rgbi_buf)
|
||||
|
||||
DHT driver
|
||||
----------
|
||||
|
||||
The DHT driver is implemented in software and works on all pins::
|
||||
|
||||
import dht
|
||||
import machine
|
||||
|
||||
d = dht.DHT11(machine.Pin(4))
|
||||
d.measure()
|
||||
d.temperature() # eg. 23 (°C)
|
||||
d.humidity() # eg. 41 (% RH)
|
||||
|
||||
d = dht.DHT22(machine.Pin(4))
|
||||
d.measure()
|
||||
d.temperature() # eg. 23.6 (°C)
|
||||
d.humidity() # eg. 41.3 (% RH)
|
||||
|
||||
WebREPL (web browser interactive prompt)
|
||||
----------------------------------------
|
||||
|
||||
|
||||
65
docs/esp8266/tutorial/dht.rst
Normal file
65
docs/esp8266/tutorial/dht.rst
Normal file
@@ -0,0 +1,65 @@
|
||||
Temperature and Humidity
|
||||
========================
|
||||
|
||||
DHT (Digital Humidity & Temperature) sensors are low cost digital sensors with
|
||||
capacitive humidity sensors and thermistors to measure the surrounding air.
|
||||
They feature a chip that handles analog to digital conversion and provide a
|
||||
1-wire interface. Newer sensors additionally provide an I2C interface.
|
||||
|
||||
The DHT11 (blue) and DHT22 (white) sensors provide the same 1-wire interface,
|
||||
however, the DHT22 requires a separate object as it has more complex
|
||||
calculation. DHT22 have 1 decimal place resolution for both humidity and
|
||||
temperature readings. DHT11 have whole number for both.
|
||||
|
||||
A custom 1-wire protocol, which is different to Dallas 1-wire, is used to get
|
||||
the measurements from the sensor. The payload consists of a humidity value,
|
||||
a temperature value and a checksum.
|
||||
|
||||
To use the 1-wire interface, construct the objects referring to their data pin::
|
||||
|
||||
>>> import dht
|
||||
>>> import machine
|
||||
>>> d = dht.DHT11(machine.Pin(4))
|
||||
|
||||
>>> import dht
|
||||
>>> import machine
|
||||
>>> d = dht.DHT22(machine.Pin(4))
|
||||
|
||||
Then measure and read their values with::
|
||||
|
||||
>>> d.measure()
|
||||
>>> d.temperature()
|
||||
>>> d.humidity()
|
||||
|
||||
Values returned from ``temperature()`` are in degrees Celsius and values
|
||||
returned from ``humidity()`` are a percentage of relative humidity.
|
||||
|
||||
The DHT11 can be called no more than once per second and the DHT22 once every
|
||||
two seconds for most accurate results. Sensor accuracy will degrade over time.
|
||||
Each sensor supports a different operating range. Refer to the product
|
||||
datasheets for specifics.
|
||||
|
||||
In 1-wire mode, only three of the four pins are used and in I2C mode, all four
|
||||
pins are used. Older sensors may still have 4 pins even though they do not
|
||||
support I2C. The 3rd pin is simply not connected.
|
||||
|
||||
Pin configurations:
|
||||
|
||||
Sensor without I2C in 1-wire mode (eg. DHT11, DHT22, AM2301, AM2302):
|
||||
|
||||
1=VDD, 2=Data, 3=NC, 4=GND
|
||||
|
||||
Sensor with I2C in 1-wire mode (eg. DHT12, AM2320, AM2321, AM2322):
|
||||
|
||||
1=VDD, 2=Data, 3=GND, 4=GND
|
||||
|
||||
Sensor with I2C in I2C mode (eg. DHT12, AM2320, AM2321, AM2322):
|
||||
|
||||
1=VDD, 2=SDA, 3=GND, 4=SCL
|
||||
|
||||
You should use pull-up resistors for the Data, SDA and SCL pins.
|
||||
|
||||
To make newer I2C sensors work in backwards compatible 1-wire mode, you must
|
||||
connect both pins 3 and 4 to GND. This disables the I2C interface.
|
||||
|
||||
DHT22 sensors are now sold under the name AM2302 and are otherwise identical.
|
||||
@@ -29,4 +29,5 @@ to `<https://www.python.org>`__.
|
||||
powerctrl.rst
|
||||
onewire.rst
|
||||
neopixel.rst
|
||||
dht.rst
|
||||
nextsteps.rst
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
Introduction to MicroPython on the ESP8266
|
||||
==========================================
|
||||
.. _intro:
|
||||
|
||||
Getting started with MicroPython on the ESP8266
|
||||
===============================================
|
||||
|
||||
Using MicroPython is a great way to get the most of your ESP8266 board. And
|
||||
vice versa, the ESP8266 chip is a great platform for using MicroPython. This
|
||||
@@ -74,8 +76,9 @@ PC. You may also need to reduce the baudrate if you get errors when flashing
|
||||
(eg down to 115200). The filename of the firmware should also match the file
|
||||
that you have.
|
||||
|
||||
If you have a NodeMCU board, you may need to use the following command to deploy
|
||||
the firmware (note the "-fm dio" option)::
|
||||
For some boards with a particular FlashROM configuration (e.g. some variants of
|
||||
a NodeMCU board) you may need to use the following command to deploy
|
||||
the firmware (note the ``-fm dio`` option)::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m -fm dio 0 esp8266-2016-05-03-v1.8.bin
|
||||
|
||||
@@ -100,3 +103,64 @@ be the same everytime, and most likely different for all ESP8266 chips). The
|
||||
password for the WiFi is micropythoN (note the upper-case N). Its IP address
|
||||
will be 192.168.4.1 once you connect to its network. WiFi configuration will
|
||||
be discussed in more detail later in the tutorial.
|
||||
|
||||
Troubleshooting installation problems
|
||||
-------------------------------------
|
||||
|
||||
If you experience problems during flashing or with running firmware immediately
|
||||
after it, here are troubleshooting recommendations:
|
||||
|
||||
* Be aware of and try to exclude hardware problems. There are 2 common problems:
|
||||
bad power source quality and worn-out/defective FlashROM. Speaking of power
|
||||
source, not just raw amperage is important, but also low ripple and noise/EMI
|
||||
in general. If you experience issues with self-made or wall-wart style power
|
||||
supply, try USB power from a computer. Unearthed power supplies are also known
|
||||
to cause problems as they source of increased EMI (electromagnetic interference)
|
||||
- at the very least, and may lead to electrical devices breakdown. So, you are
|
||||
advised to avoid using unearthed power connections when working with ESP8266
|
||||
and other boards. In regard to FlashROM hardware problems, there are independent
|
||||
(not related to MicroPython in any way) reports
|
||||
`(e.g.) <http://internetofhomethings.com/homethings/?p=538>`_
|
||||
that on some ESP8266 modules, FlashROM can be programmed as little as 20 times
|
||||
before programming errors occur. This is *much* less than 100,000 programming
|
||||
cycles cited for FlashROM chips of a type used with ESP8266 by reputable
|
||||
vendors, which points to either production rejects, or second-hand worn-out
|
||||
flash chips to be used on some (apparently cheap) modules/boards. You may want
|
||||
to use your best judgement about source, price, documentation, warranty,
|
||||
post-sales support for the modules/boards you purchase.
|
||||
|
||||
* The flashing instructions above use flashing speed of 460800 baud, which is
|
||||
good compromise between speed and stability. However, depending on your
|
||||
module/board, USB-UART convertor, cables, host OS, etc., the above baud
|
||||
rate may be too high and lead to errors. Try a more common 115200 baud
|
||||
rate instead in such cases.
|
||||
|
||||
* If lower baud rate didn't help, you may want to try older version of
|
||||
esptool.py, which had a different programming algorithm::
|
||||
pip install esptool==1.0.1
|
||||
|
||||
* The ``--flash_size`` option in the commands above is mandatory. Omitting
|
||||
it will lead to a corrupted firmware.
|
||||
|
||||
* To catch incorrect flash content (e.g. from a defective sector on a chip),
|
||||
add ``--verify`` switch to the commands above.
|
||||
|
||||
* Additionally, you can check the firmware integrity from a MicroPython REPL
|
||||
prompt (assuming you were able to flash it and ``--verify`` option doesn't
|
||||
report errors)::
|
||||
import esp
|
||||
esp.check_fw()
|
||||
If the last output value is True, the firmware is OK. Otherwise, it's
|
||||
corrupted and need to be reflashed correctly.
|
||||
|
||||
* If you experience any issues with another flashing application (not
|
||||
esptool.py), try esptool.py, it is a generally accepted flashing
|
||||
application in the ESP8266 community.
|
||||
|
||||
* If you still experience problems with even flashing the firmware, please
|
||||
refer to esptool.py project page, https://github.com/themadinventor/esptool
|
||||
for additional documentation and bug tracker where you can report problems.
|
||||
|
||||
* If you are able to flash firmware, but ``--verify`` option or
|
||||
``esp.check_fw()`` return errors even after multiple retries, you
|
||||
may have a defective FlashROM chip, as explained above.
|
||||
|
||||
@@ -6,19 +6,19 @@ The 1-wire bus is a serial bus that uses just a single wire for communication
|
||||
is a very popular 1-wire device, and here we show how to use the onewire module
|
||||
to read from such a device.
|
||||
|
||||
For the following code to work you need to have at least one DS18B20 temperature
|
||||
For the following code to work you need to have at least one DS18S20 or DS18B20 temperature
|
||||
sensor with its data line connected to GPIO12. You must also power the sensors
|
||||
and connect a 4.7k Ohm resistor between the data pin and the power pin. ::
|
||||
|
||||
import time
|
||||
import machine
|
||||
import onewire
|
||||
import onewire, ds18x20
|
||||
|
||||
# the device is on GPIO12
|
||||
dat = machine.Pin(12)
|
||||
|
||||
# create the onewire object
|
||||
ds = onewire.DS18B20(onewire.OneWire(dat))
|
||||
ds = ds18x20.DS18X20(onewire.OneWire(dat))
|
||||
|
||||
# scan for devices on the bus
|
||||
roms = ds.scan()
|
||||
|
||||
@@ -14,7 +14,7 @@ Here, the "0" is the pin that you want to access. Usually you want to
|
||||
configure the pin to be input or output, and you do this when constructing
|
||||
it. To make an input pin use::
|
||||
|
||||
>>> pin = machine.Pin(0, machine.Pin.OUT, machine.Pin.PULL_UP)
|
||||
>>> pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
|
||||
|
||||
You can either use PULL_UP or None for the input pull-mode. If it's
|
||||
not specified then it defaults to None, which is no pull resistor.
|
||||
|
||||
@@ -36,7 +36,7 @@ WebREPL - a prompt over WiFi
|
||||
WebREPL allows you to use the Python prompt over WiFi, connecting through a
|
||||
browser. The latest versions of Firefox and Chrome are supported.
|
||||
|
||||
For your convinience, WebREPL client is hosted at
|
||||
For your convenience, WebREPL client is hosted at
|
||||
`<http://micropython.org/webrepl>`__ . Alternatively, you can install it
|
||||
locally from the the GitHub repository
|
||||
`<https://github.com/micropython/webrepl>`__ .
|
||||
|
||||
30
docs/library/array.rst
Normal file
30
docs/library/array.rst
Normal file
@@ -0,0 +1,30 @@
|
||||
:mod:`array` -- arrays of numeric data
|
||||
======================================
|
||||
|
||||
.. module:: array
|
||||
:synopsis: efficient arrays of numeric data
|
||||
|
||||
See `Python array <https://docs.python.org/3/library/array.html>`_ for more
|
||||
information.
|
||||
|
||||
Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``,
|
||||
``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the
|
||||
floating-point support).
|
||||
|
||||
Classes
|
||||
-------
|
||||
|
||||
.. class:: array.array(typecode, [iterable])
|
||||
|
||||
Create array with elements of given type. Initial contents of the
|
||||
array are given by an `iterable`. If it is not provided, an empty
|
||||
array is created.
|
||||
|
||||
.. method:: append(val)
|
||||
|
||||
Append new element to the end of array, growing it.
|
||||
|
||||
.. method:: extend(iterable)
|
||||
|
||||
Append new elements as contained in an iterable to the end of
|
||||
array, growing it.
|
||||
@@ -1,7 +1,7 @@
|
||||
Builtin Functions
|
||||
=================
|
||||
|
||||
All builtin functions are described here. They are alse available via
|
||||
All builtin functions are described here. They are also available via
|
||||
``builtins`` module.
|
||||
|
||||
.. function:: abs()
|
||||
|
||||
@@ -15,7 +15,7 @@ Functions
|
||||
Get or set the sleep type.
|
||||
|
||||
If the ``sleep_type`` parameter is provided, sets the sleep type to its
|
||||
value. If the function is called wihout parameters, returns the current
|
||||
value. If the function is called without parameters, returns the current
|
||||
sleep type.
|
||||
|
||||
The possible sleep types are defined as constants:
|
||||
|
||||
@@ -51,6 +51,7 @@ library.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
cmath.rst
|
||||
gc.rst
|
||||
@@ -75,6 +76,7 @@ library.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
cmath.rst
|
||||
gc.rst
|
||||
@@ -99,6 +101,7 @@ library.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
gc.rst
|
||||
select.rst
|
||||
@@ -116,6 +119,7 @@ library.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
gc.rst
|
||||
math.rst
|
||||
|
||||
@@ -84,7 +84,7 @@ Methods
|
||||
|
||||
- ``None`` - no pull up or down resistor.
|
||||
- ``Pin.PULL_UP`` - pull up resistor enabled.
|
||||
- ``Pin.PULL_DOWN`` - pull down resitor enabled.
|
||||
- ``Pin.PULL_DOWN`` - pull down resistor enabled.
|
||||
|
||||
- ``drive`` can be one of:
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ Methods
|
||||
|
||||
.. method:: RTC.alarm(id, time, /*, repeat=False)
|
||||
|
||||
Set the RTC alarm. Time might be either a milllisecond value to program the alarm to
|
||||
Set the RTC alarm. Time might be either a millisecond value to program the alarm to
|
||||
current time + time_in_ms in the future, or a datetimetuple. If the time passed is in
|
||||
milliseconds, repeat can be set to ``True`` to make the alarm periodic.
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ Methods
|
||||
respectively.
|
||||
- ``bits`` is the width of each transfer, accepted values are 8, 16 and 32.
|
||||
- ``firstbit`` can be ``SPI.MSB`` only.
|
||||
- ``pins`` is an optional tupple with the pins to assign to the SPI bus.
|
||||
- ``pins`` is an optional tuple with the pins to assign to the SPI bus.
|
||||
|
||||
.. method:: SPI.deinit()
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ Methods
|
||||
If only a channel identifier passed, then a previously initialized channel
|
||||
object is returned (or ``None`` if there is no previous channel).
|
||||
|
||||
Othwerwise, a TimerChannel object is initialized and returned.
|
||||
Otherwise, a TimerChannel object is initialized and returned.
|
||||
|
||||
The operating mode is is the one configured to the Timer object that was used to
|
||||
create the channel.
|
||||
@@ -152,7 +152,7 @@ Methods
|
||||
|
||||
.. method:: timerchannel.irq(\*, trigger, priority=1, handler=None)
|
||||
|
||||
The behavior of this callback is heaviliy dependent on the operating
|
||||
The behavior of this callback is heavily dependent on the operating
|
||||
mode of the timer channel:
|
||||
|
||||
- If mode is ``Timer.PERIODIC`` the callback is executed periodically
|
||||
|
||||
@@ -167,7 +167,7 @@ Methods
|
||||
.. data:: UART.EVEN
|
||||
.. data:: UART.ODD
|
||||
|
||||
parity types (anlong with ``None``)
|
||||
parity types (along with ``None``)
|
||||
|
||||
.. data:: UART.RX_ANY
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ Example usage::
|
||||
wdt = WDT(timeout=2000) # enable it with a timeout of 2s
|
||||
wdt.feed()
|
||||
|
||||
Availability of this class: pyboard, WiPy.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ Power related functions
|
||||
Gates the clock to the CPU, useful to reduce power consumption at any time during
|
||||
short or long periods. Peripherals continue working and execution resumes as soon
|
||||
as any interrupt is triggered (on many ports this includes system timer
|
||||
interrupt occuring at regular intervals on the order of millisecond).
|
||||
interrupt occurring at regular intervals on the order of millisecond).
|
||||
|
||||
.. function:: sleep()
|
||||
|
||||
@@ -96,7 +96,7 @@ Miscellaneous functions
|
||||
|
||||
.. function:: unique_id()
|
||||
|
||||
Returns a byte string with a unique idenifier of a board/SoC. It will vary
|
||||
Returns a byte string with a unique identifier of a board/SoC. It will vary
|
||||
from a board/SoC instance to another, if underlying hardware allows. Length
|
||||
varies by hardware (so use substring of a full value if you expect a short
|
||||
ID). In some MicroPython ports, ID corresponds to the network MAC address.
|
||||
@@ -125,7 +125,7 @@ Constants
|
||||
|
||||
irq wake values
|
||||
|
||||
.. data:: machine.POWER_ON
|
||||
.. data:: machine.PWRON_RESET
|
||||
.. data:: machine.HARD_RESET
|
||||
.. data:: machine.WDT_RESET
|
||||
.. data:: machine.DEEPSLEEP_RESET
|
||||
|
||||
@@ -237,7 +237,7 @@ For example::
|
||||
Get or set the PHY mode.
|
||||
|
||||
If the ``mode`` parameter is provided, sets the mode to its value. If
|
||||
the function is called wihout parameters, returns the current mode.
|
||||
the function is called without parameters, returns the current mode.
|
||||
|
||||
The possible modes are defined as constants:
|
||||
* ``MODE_11B`` -- IEEE 802.11b,
|
||||
@@ -319,7 +319,7 @@ For example::
|
||||
* ``STAT_WRONG_PASSWORD`` -- failed due to incorrect password,
|
||||
* ``STAT_NO_AP_FOUND`` -- failed because no access point replied,
|
||||
* ``STAT_CONNECT_FAIL`` -- failed due to other problems,
|
||||
* ``STAT_GOT_IP`` -- connection susccessful.
|
||||
* ``STAT_GOT_IP`` -- connection successful.
|
||||
|
||||
.. method:: wlan.isconnected()
|
||||
|
||||
@@ -329,7 +329,7 @@ For example::
|
||||
|
||||
.. method:: wlan.ifconfig([(ip, subnet, gateway, dns)])
|
||||
|
||||
Get/set IP-level network interface paremeters: IP address, subnet mask,
|
||||
Get/set IP-level network interface parameters: IP address, subnet mask,
|
||||
gateway and DNS server. 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::
|
||||
@@ -343,8 +343,8 @@ For example::
|
||||
with additional parameters beyond standard IP configuration (as dealt with by
|
||||
``wlan.ifconfig()``). These include network-specific and hardware-specific
|
||||
parameters. For setting parameters, keyword argument syntax should be used,
|
||||
multiple parameters can be set at once. For querying, paremeters name should
|
||||
be quoted as a string, and only one paramter can be queries at time::
|
||||
multiple parameters can be set at once. For querying, parameters name should
|
||||
be quoted as a string, and only one parameter can be queries at time::
|
||||
|
||||
# Set WiFi access point name (formally known as ESSID) and WiFi channel
|
||||
ap.config(essid='My AP', channel=11)
|
||||
@@ -397,7 +397,7 @@ For example::
|
||||
.. note::
|
||||
|
||||
The ``WLAN`` constructor is special in the sense that if no arguments besides the id are given,
|
||||
it will return the already exisiting ``WLAN`` instance without re-configuring it. This is
|
||||
it will return the already existing ``WLAN`` instance without re-configuring it. This is
|
||||
because ``WLAN`` is a system feature of the WiPy. If the already existing instance is not
|
||||
initialized it will do the same as the other constructors an will initialize it with default
|
||||
values.
|
||||
|
||||
@@ -13,7 +13,7 @@ class ADC -- analog to digital conversion
|
||||
adc = pyb.ADC(pin) # create an analog object from a pin
|
||||
val = adc.read() # read an analog value
|
||||
|
||||
adc = pyb.ADCAll(resolution) # creale an ADCAll object
|
||||
adc = pyb.ADCAll(resolution) # create an ADCAll object
|
||||
val = adc.read_channel(channel) # read the given channel
|
||||
val = adc.read_core_temp() # read MCU temperature
|
||||
val = adc.read_core_vbat() # read MCU VBAT
|
||||
|
||||
@@ -79,7 +79,7 @@ Methods
|
||||
.. method:: DAC.triangle(freq)
|
||||
|
||||
Generate a triangle wave. The value on the DAC output changes at
|
||||
the given frequency, and the frequence of the repeating triangle wave
|
||||
the given frequency, and the frequency of the repeating triangle wave
|
||||
itself is 2048 times smaller.
|
||||
|
||||
.. method:: DAC.write(value)
|
||||
|
||||
@@ -7,7 +7,7 @@ class ExtInt -- configure I/O pins to interrupt on external events
|
||||
There are a total of 22 interrupt lines. 16 of these can come from GPIO pins
|
||||
and the remaining 6 are from internal sources.
|
||||
|
||||
For lines 0 thru 15, a given line can map to the corresponding line from an
|
||||
For lines 0 through 15, a given line can map to the corresponding line from an
|
||||
arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and
|
||||
line 1 can map to Px1 where x is A, B, C, ... ::
|
||||
|
||||
@@ -27,7 +27,7 @@ explanation, along with various techniques for debouncing.
|
||||
Trying to register 2 callbacks onto the same pin will throw an exception.
|
||||
|
||||
If pin is passed as an integer, then it is assumed to map to one of the
|
||||
internal interrupt sources, and must be in the range 16 thru 22.
|
||||
internal interrupt sources, and must be in the range 16 through 22.
|
||||
|
||||
All other pin objects go through the pin mapper to come up with one of the
|
||||
gpio pins. ::
|
||||
|
||||
@@ -39,7 +39,7 @@ Printing the i2c object gives you information about its configuration.
|
||||
|
||||
You can specify a timeout (in ms)::
|
||||
|
||||
i2c.send(b'123', timeout=2000) # timout after 2 seconds
|
||||
i2c.send(b'123', timeout=2000) # timeout after 2 seconds
|
||||
|
||||
A master must specify the recipient's address::
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ Constants
|
||||
class PinAF -- Pin Alternate Functions
|
||||
======================================
|
||||
|
||||
A Pin represents a physical pin on the microcprocessor. Each pin
|
||||
A Pin represents a physical pin on the microprocessor. Each pin
|
||||
can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF
|
||||
object represents a particular function for a pin.
|
||||
|
||||
@@ -240,7 +240,7 @@ Constants
|
||||
x3 = pyb.Pin.board.X3
|
||||
x3_af = x3.af_list()
|
||||
|
||||
x3_af will now contain an array of PinAF objects which are availble on
|
||||
x3_af will now contain an array of PinAF objects which are available on
|
||||
pin X3.
|
||||
|
||||
For the pyboard, x3_af would contain:
|
||||
|
||||
@@ -73,7 +73,7 @@ Methods
|
||||
value, which is an integer in the range [-511 : 512]. With one
|
||||
argument it sets the RTC calibration.
|
||||
|
||||
The RTC Smooth Calibration mechanism addjusts the RTC clock rate by
|
||||
The RTC Smooth Calibration mechanism adjusts the RTC clock rate by
|
||||
adding or subtracting the given number of ticks from the 32768 Hz
|
||||
clock over a 32 second period (corresponding to 2^20 clock ticks.)
|
||||
Each tick added will speed up the clock by 1 part in 2^20, or 0.954
|
||||
|
||||
@@ -78,7 +78,7 @@ Methods
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
- ``freq`` --- specifies the periodic frequency of the timer. You migh also
|
||||
- ``freq`` --- specifies the periodic frequency of the timer. You might also
|
||||
view this as the frequency with which the timer goes through one complete cycle.
|
||||
|
||||
- ``prescaler`` [0-0xffff] - specifies the value to be loaded into the
|
||||
@@ -97,7 +97,7 @@ Methods
|
||||
|
||||
- ``Timer.UP`` - configures the timer to count from 0 to ARR (default)
|
||||
- ``Timer.DOWN`` - configures the timer to count from ARR down to 0.
|
||||
- ``Timer.CENTER`` - confgures the timer to count from 0 to ARR and
|
||||
- ``Timer.CENTER`` - configures the timer to count from 0 to ARR and
|
||||
then back down to 0.
|
||||
|
||||
- ``div`` can be one of 1, 2, or 4. Divides the timer clock to determine
|
||||
@@ -109,7 +109,7 @@ Methods
|
||||
transitions on complimentary channels (both channels will be inactive)
|
||||
for this time). ``deadtime`` may be an integer between 0 and 1008, with
|
||||
the following restrictions: 0-128 in steps of 1. 128-256 in steps of
|
||||
2, 256-512 in steps of 8, and 512-1008 in steps of 16. ``deadime``
|
||||
2, 256-512 in steps of 8, and 512-1008 in steps of 16. ``deadtime``
|
||||
measures ticks of ``source_freq`` divided by ``div`` clock ticks.
|
||||
``deadtime`` is only available on timers 1 and 8.
|
||||
|
||||
@@ -141,7 +141,7 @@ Methods
|
||||
If only a channel number is passed, then a previously initialized channel
|
||||
object is returned (or ``None`` if there is no previous channel).
|
||||
|
||||
Othwerwise, a TimerChannel object is initialized and returned.
|
||||
Otherwise, a TimerChannel object is initialized and returned.
|
||||
|
||||
Each channel can be configured to perform pwm, output compare, or
|
||||
input capture. All channels share the same underlying timer, which means
|
||||
@@ -183,7 +183,7 @@ Methods
|
||||
- ``polarity`` can be one of:
|
||||
|
||||
- ``Timer.HIGH`` - output is active high
|
||||
- ``Timer.LOW`` - output is acive low
|
||||
- ``Timer.LOW`` - output is active low
|
||||
|
||||
Optional keyword arguments for Timer.IC modes:
|
||||
|
||||
|
||||
28
docs/library/pyb.USB_HID.rst
Normal file
28
docs/library/pyb.USB_HID.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
.. currentmodule:: pyb
|
||||
|
||||
class USB_HID -- USB Human Interface Device (HID)
|
||||
=================================================
|
||||
|
||||
The USB_HID class allows creation of an object representing the USB
|
||||
Human Interface Device (HID) interface. It can be used to emulate
|
||||
a peripheral such as a mouse or keyboard.
|
||||
|
||||
Before you can use this class, you need to use :meth:`pyb.usb_mode()` to set the USB mode to include the HID interface.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.USB_HID()
|
||||
|
||||
Create a new USB_HID object.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: USB_HID.send(data)
|
||||
|
||||
Send data over the USB HID interface:
|
||||
|
||||
- ``data`` is the data to send (a tuple/list of integers, or a
|
||||
bytearray).
|
||||
@@ -46,7 +46,7 @@ Time related functions
|
||||
Returns the number of milliseconds which have elapsed since ``start``.
|
||||
|
||||
This function takes care of counter wrap, and always returns a positive
|
||||
number. This means it can be used to measure periods upto about 12.4 days.
|
||||
number. This means it can be used to measure periods up to about 12.4 days.
|
||||
|
||||
Example::
|
||||
|
||||
@@ -59,7 +59,7 @@ Time related functions
|
||||
Returns the number of microseconds which have elapsed since ``start``.
|
||||
|
||||
This function takes care of counter wrap, and always returns a positive
|
||||
number. This means it can be used to measure periods upto about 17.8 minutes.
|
||||
number. This means it can be used to measure periods up to about 17.8 minutes.
|
||||
|
||||
Example::
|
||||
|
||||
@@ -188,7 +188,7 @@ Miscellaneous functions
|
||||
Takes a 4-tuple (or list) and sends it to the USB host (the PC) to
|
||||
signal a HID mouse-motion event.
|
||||
|
||||
.. note:: This function is deprecated. Use pyb.USB_HID().send(...) instead.
|
||||
.. note:: This function is deprecated. Use :meth:`pyb.USB_HID.send()` instead.
|
||||
|
||||
.. function:: info([dump_alloc_table])
|
||||
|
||||
@@ -254,6 +254,33 @@ Miscellaneous functions
|
||||
|
||||
Returns a string of 12 bytes (96 bits), which is the unique ID of the MCU.
|
||||
|
||||
.. function:: usb_mode([modestr], vid=0xf055, pid=0x9801, hid=pyb.hid_mouse)
|
||||
|
||||
If called with no arguments, return the current USB mode as a string.
|
||||
|
||||
If called with ``modestr`` provided, attempts to set USB mode.
|
||||
This can only be done when called from ``boot.py`` before
|
||||
:meth:`pyb.main()` has been called. The following values of
|
||||
``modestr`` are understood:
|
||||
|
||||
- ``None``: disables USB
|
||||
- ``'VCP'``: enable with VCP (Virtual COM Port) interface
|
||||
- ``'VCP+MSC'``: enable with VCP and MSC (mass storage device class)
|
||||
- ``'VCP+HID'``: enable with VCP and HID (human interface device)
|
||||
|
||||
For backwards compatibility, ``'CDC'`` is understood to mean
|
||||
``'VCP'`` (and similarly for ``'CDC+MSC'`` and ``'CDC+HID'``).
|
||||
|
||||
The ``vid`` and ``pid`` parameters allow you to specify the VID
|
||||
(vendor id) and PID (product id).
|
||||
|
||||
If enabling HID mode, you may also specify the HID details by
|
||||
passing the ``hid`` keyword parameter. It takes a tuple of
|
||||
(subclass, protocol, max packet length, polling interval, report
|
||||
descriptor). By default it will set appropriate values for a USB
|
||||
mouse. There is also a ``pyb.hid_keyboard`` constant, which is an
|
||||
appropriate tuple for a USB keyboard.
|
||||
|
||||
Classes
|
||||
-------
|
||||
|
||||
@@ -277,4 +304,5 @@ Classes
|
||||
pyb.Switch.rst
|
||||
pyb.Timer.rst
|
||||
pyb.UART.rst
|
||||
pyb.USB_HID.rst
|
||||
pyb.USB_VCP.rst
|
||||
|
||||
@@ -17,7 +17,7 @@ Functions
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
If additional argument, `sep` is supplied, it is used as a seperator
|
||||
If additional argument, `sep` is supplied, it is used as a separator
|
||||
between hexadecimal values.
|
||||
|
||||
.. function:: unhexlify(data)
|
||||
|
||||
@@ -13,10 +13,10 @@ Classes
|
||||
.. function:: namedtuple(name, fields)
|
||||
|
||||
This is factory function to create a new namedtuple type with a specific
|
||||
name and set of fields. A namedtyple is a subclass of tuple which allows
|
||||
name and set of fields. A namedtuple is a subclass of tuple which allows
|
||||
to access its fields not just by numeric index, but also with an attribute
|
||||
access syntax using symbolic field names. Fields is a sequence of strings
|
||||
specifying field names. For compatibily with CPython it can also be a
|
||||
specifying field names. For compatibility with CPython it can also be a
|
||||
a string with space-separated field named (but this is less efficient).
|
||||
Example of use::
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ Module contents
|
||||
|
||||
.. data:: BIG_ENDIAN
|
||||
|
||||
Layour type for a big-endian packed structure.
|
||||
Layout type for a big-endian packed structure.
|
||||
|
||||
.. data:: NATIVE
|
||||
|
||||
@@ -184,7 +184,7 @@ Subscripting a 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, when you need to use ``[0]`` operator
|
||||
except for pointer dereference, when you need to use ``[0]`` operator
|
||||
instead of ``*``.
|
||||
|
||||
Limitations
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
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
|
||||
single algorithm can cover both use cases of "any hash algorithm" and
|
||||
security-related usage, and thus save space omitting legacy algorithms
|
||||
like MD5 or SHA1.
|
||||
|
||||
@@ -53,7 +53,7 @@ Constructors
|
||||
|
||||
Example::
|
||||
|
||||
hash = uhashlib.sha1('abcd1234', 1001) # lenght of the initial piece is multiple of 4 bytes
|
||||
hash = uhashlib.sha1('abcd1234', 1001) # length of the initial piece is multiple of 4 bytes
|
||||
hash.update('1234') # also multiple of 4 bytes
|
||||
...
|
||||
hash.update('12345') # last chunk may be of any length
|
||||
@@ -68,7 +68,7 @@ Methods
|
||||
|
||||
.. method:: hash.digest()
|
||||
|
||||
Return hash for all data passed thru hash, as a bytes object. After this
|
||||
Return hash for all data passed through hash, as a bytes object. After this
|
||||
method is called, more data cannot be fed into hash any longer.
|
||||
|
||||
.. only:: port_wipy
|
||||
|
||||
@@ -12,7 +12,7 @@ Functions
|
||||
|
||||
.. function:: open(name, mode='r', **kwargs)
|
||||
|
||||
Open a file. Builtin ``open()`` function is alised to this function.
|
||||
Open a file. Builtin ``open()`` function is aliased to this function.
|
||||
All ports (which provide access to file system) are required to support
|
||||
`mode` parameter, but support for other arguments vary by port.
|
||||
|
||||
@@ -38,8 +38,9 @@ Classes
|
||||
opened with "b" modifier). Initial contents of file-like objects
|
||||
can be specified with `string` parameter (should be normal string
|
||||
for `StringIO` or bytes object for `BytesIO`). All the usual file
|
||||
methods like ``read()``, ``write()``, ``close()`` are available on
|
||||
these objects, and additionally, following method:
|
||||
methods like ``read()``, ``write()``, ``seek()``, ``flush()``,
|
||||
``close()`` are available on these objects, and additionally, a
|
||||
following method:
|
||||
|
||||
.. method:: getvalue()
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ Functions
|
||||
|
||||
.. function:: unmount(path)
|
||||
|
||||
Unmounts a prevoulsy mounted block device from the given path.
|
||||
Unmounts a previously mounted block device from the given path.
|
||||
|
||||
.. function:: mkfs(block_device or path)
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ Functions
|
||||
.. function:: time()
|
||||
|
||||
Returns the number of seconds, as an integer, since the Epoch, assuming that underlying
|
||||
RTC is set and maintained as decsribed above. If an RTC is not set, this function returns
|
||||
RTC is set and maintained as described above. If an RTC is not set, this function returns
|
||||
number of seconds since a port-specific reference point in time (for embedded boards without
|
||||
a battery-backed RTC, usually since power up or reset). If you want to develop portable
|
||||
MicroPython application, you should not rely on this function to provide higher than second
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
Quick reference for the pyboard
|
||||
===============================
|
||||
|
||||
The below pinout is for PYBv1.0. You can also view pinouts for
|
||||
other versions of the pyboard:
|
||||
`PYBv1.1 <http://micropython.org/resources/pybv11-pinout.jpg>`__
|
||||
or `PYBLITEv1.0-AC <http://micropython.org/resources/pyblitev10ac-pinout.jpg>`__
|
||||
or `PYBLITEv1.0 <http://micropython.org/resources/pyblitev10-pinout.jpg>`__.
|
||||
|
||||
.. image:: http://micropython.org/resources/pybv10-pinout.jpg
|
||||
:alt: PYBv1.0 pinout
|
||||
:width: 700px
|
||||
@@ -14,14 +20,25 @@ See :mod:`pyb`. ::
|
||||
|
||||
import pyb
|
||||
|
||||
pyb.delay(50) # wait 50 milliseconds
|
||||
pyb.millis() # number of milliseconds since bootup
|
||||
pyb.repl_uart(pyb.UART(1, 9600)) # duplicate REPL on UART(1)
|
||||
pyb.wfi() # pause CPU, waiting for interrupt
|
||||
pyb.freq() # get CPU and bus frequencies
|
||||
pyb.freq(60000000) # set CPU freq to 60MHz
|
||||
pyb.stop() # stop CPU, waiting for external interrupt
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
Use the :mod:`time <utime>` module::
|
||||
|
||||
import time
|
||||
|
||||
time.sleep(1) # sleep for 1 second
|
||||
time.sleep_ms(500) # sleep for 500 milliseconds
|
||||
time.sleep_us(10) # sleep for 10 microseconds
|
||||
start = time.ticks_ms() # get value of millisecond counter
|
||||
delta = time.ticks_diff(start, time.ticks_ms()) # compute time difference
|
||||
|
||||
LEDs
|
||||
----
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ We set up timer 2 as follows::
|
||||
|
||||
The prescaler is set at 83, which makes this timer count at 1 MHz.
|
||||
This is because the CPU clock, running at 168 MHz, is divided by
|
||||
2 and then by prescaler+1, giving a freqency of 168 MHz/2/(83+1)=1 MHz
|
||||
2 and then by prescaler+1, giving a frequency of 168 MHz/2/(83+1)=1 MHz
|
||||
for timer 2. The period is set to a large number so that the timer
|
||||
can count up to a large number before wrapping back around to zero.
|
||||
In this case it will take about 17 minutes before it cycles back to
|
||||
|
||||
@@ -13,23 +13,23 @@ will look something like this::
|
||||
|
||||
import pyb
|
||||
#pyb.main('main.py') # main script to run after this one
|
||||
#pyb.usb_mode('CDC+MSC') # act as a serial and a storage device
|
||||
#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
|
||||
#pyb.usb_mode('VCP+MSC') # act as a serial and a storage device
|
||||
#pyb.usb_mode('VCP+HID') # act as a serial device and a mouse
|
||||
|
||||
To enable the mouse mode, uncomment the last line of the file, to
|
||||
make it look like::
|
||||
|
||||
pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
|
||||
pyb.usb_mode('VCP+HID') # act as a serial device and a mouse
|
||||
|
||||
If you already changed your ``boot.py`` file, then the minimum code it
|
||||
needs to work is::
|
||||
|
||||
import pyb
|
||||
pyb.usb_mode('CDC+HID')
|
||||
pyb.usb_mode('VCP+HID')
|
||||
|
||||
This tells the pyboard to configure itself as a CDC (serial) and HID
|
||||
(human interface device, in our case a mouse) USB device when it boots
|
||||
up.
|
||||
This tells the pyboard to configure itself as a VCP (Virtual COM Port,
|
||||
ie serial port) and HID (human interface device, in our case a mouse)
|
||||
USB device when it boots up.
|
||||
|
||||
Eject/unmount the pyboard drive and reset it using the RST switch.
|
||||
Your PC should now detect the pyboard as a mouse!
|
||||
@@ -41,7 +41,8 @@ To get the py-mouse to do anything we need to send mouse events to the PC.
|
||||
We will first do this manually using the REPL prompt. Connect to your
|
||||
pyboard using your serial program and type the following::
|
||||
|
||||
>>> pyb.hid((0, 10, 0, 0))
|
||||
>>> hid = pyb.USB_HID()
|
||||
>>> hid.send((0, 10, 0, 0))
|
||||
|
||||
Your mouse should move 10 pixels to the right! In the command above you
|
||||
are sending 4 pieces of information: button status, x, y and scroll. The
|
||||
@@ -52,7 +53,7 @@ Let's make the mouse oscillate left and right::
|
||||
>>> import math
|
||||
>>> def osc(n, d):
|
||||
... for i in range(n):
|
||||
... pyb.hid((0, int(20 * math.sin(i / 10)), 0, 0))
|
||||
... hid.send((0, int(20 * math.sin(i / 10)), 0, 0))
|
||||
... pyb.delay(d)
|
||||
...
|
||||
>>> osc(100, 50)
|
||||
@@ -61,7 +62,7 @@ The first argument to the function ``osc`` is the number of mouse events to send
|
||||
and the second argument is the delay (in milliseconds) between events. Try
|
||||
playing around with different numbers.
|
||||
|
||||
**Excercise: make the mouse go around in a circle.**
|
||||
**Exercise: make the mouse go around in a circle.**
|
||||
|
||||
Making a mouse with the accelerometer
|
||||
-------------------------------------
|
||||
@@ -85,14 +86,14 @@ the [safe mode tutorial](tut-reset), but we repeat the instructions here:
|
||||
3. The LEDs will then cycle green to orange to green+orange and back again.
|
||||
4. Keep holding down USR until *only the orange LED is lit*, and then let
|
||||
go of the USR switch.
|
||||
5. The orange LED should flash quickly 4 times, and then turn off.
|
||||
5. The orange LED should flash quickly 4 times, and then turn off.
|
||||
6. You are now in safe mode.
|
||||
|
||||
In safe mode, the ``boot.py`` and ``main.py`` files are not executed, and so
|
||||
the pyboard boots up with default settings. This means you now have access
|
||||
to the filesystem (the USB drive should appear), and you can edit ``main.py``.
|
||||
(Leave ``boot.py`` as-is, because we still want to go back to HID-mode after
|
||||
we finish editting ``main.py``.)
|
||||
we finish editing ``main.py``.)
|
||||
|
||||
In ``main.py`` put the following code::
|
||||
|
||||
@@ -100,9 +101,10 @@ In ``main.py`` put the following code::
|
||||
|
||||
switch = pyb.Switch()
|
||||
accel = pyb.Accel()
|
||||
hid = pyb.USB_HID()
|
||||
|
||||
while not switch():
|
||||
pyb.hid((0, accel.x(), accel.y(), 0))
|
||||
hid.send((0, accel.x(), accel.y(), 0))
|
||||
pyb.delay(20)
|
||||
|
||||
Save your file, eject/unmount your pyboard drive, and reset it using the RST
|
||||
@@ -112,7 +114,7 @@ the mouse around. Try it out, and see if you can make the mouse stand still!
|
||||
Press the USR switch to stop the mouse motion.
|
||||
|
||||
You'll note that the y-axis is inverted. That's easy to fix: just put a
|
||||
minus sign in front of the y-coordinate in the ``pyb.hid()`` line above.
|
||||
minus sign in front of the y-coordinate in the ``hid.send()`` line above.
|
||||
|
||||
Restoring your pyboard to normal
|
||||
--------------------------------
|
||||
@@ -121,9 +123,9 @@ If you leave your pyboard as-is, it'll behave as a mouse everytime you plug
|
||||
it in. You probably want to change it back to normal. To do this you need
|
||||
to first enter safe mode (see above), and then edit the ``boot.py`` file.
|
||||
In the ``boot.py`` file, comment out (put a # in front of) the line with the
|
||||
``CDC+HID`` setting, so it looks like::
|
||||
``VCP+HID`` setting, so it looks like::
|
||||
|
||||
#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
|
||||
#pyb.usb_mode('VCP+HID') # act as a serial device and a mouse
|
||||
|
||||
Save your file, eject/unmount the drive, and reset the pyboard. It is now
|
||||
back to normal operating mode.
|
||||
|
||||
@@ -129,7 +129,7 @@ Non-integer data types
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These may be handled by means of arrays of the appropriate data type. For
|
||||
example, single precison floating point data may be processed as follows.
|
||||
example, single precision floating point data may be processed as follows.
|
||||
This code example takes an array of floats and replaces its contents with
|
||||
their squares.
|
||||
|
||||
@@ -172,7 +172,7 @@ thus:
|
||||
|
||||
The const() construct causes MicroPython to replace the variable name
|
||||
with its value at compile time. If constants are declared in an outer
|
||||
Python scope they can be shared between mutiple assembler functions and
|
||||
Python scope they can be shared between multiple assembler functions and
|
||||
with Python code.
|
||||
|
||||
Assembler code as class methods
|
||||
|
||||
@@ -23,7 +23,7 @@ specifiers:
|
||||
* ne Not equal
|
||||
* cs Carry set
|
||||
* cc Carry clear
|
||||
* mi Minus (negaive)
|
||||
* mi Minus (negative)
|
||||
* pl Plus (positive)
|
||||
* vs Overflow set
|
||||
* vc Overflow clear
|
||||
|
||||
@@ -24,7 +24,7 @@ This summarises the points detailed below and lists the principal recommendation
|
||||
* Where an ISR returns multiple bytes use a pre-allocated ``bytearray``. If multiple integers are to be
|
||||
shared between an ISR and the main program consider an array (``array.array``).
|
||||
* Where data is shared between the main program and an ISR, consider disabling interrupts prior to accessing
|
||||
the data in the main program and re-enabling them immediately afterwards (see Critcal Sections).
|
||||
the data in the main program and re-enabling them immediately afterwards (see Critical Sections).
|
||||
* Allocate an emergency exception buffer (see below).
|
||||
|
||||
|
||||
@@ -110,6 +110,19 @@ the flag. The memory allocation occurs in the main program code when the object
|
||||
The MicroPython library I/O methods usually provide an option to use a pre-allocated buffer. For
|
||||
example ``pyb.i2c.recv()`` can accept a mutable buffer as its first argument: this enables its use in an ISR.
|
||||
|
||||
A means of creating an object without employing a class or globals is as follows:
|
||||
|
||||
.. code:: python
|
||||
|
||||
def set_volume(t, buf=bytearray(3)):
|
||||
buf[0] = 0xa5
|
||||
buf[1] = t >> 4
|
||||
buf[2] = 0x5a
|
||||
return buf
|
||||
|
||||
The compiler instantiates the default ``buf`` argument when the function is
|
||||
loaded for the first time (usually when the module it's in is imported).
|
||||
|
||||
Use of Python objects
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -300,3 +313,20 @@ that access to the critical variables is denied. A simple example of a mutex may
|
||||
but only for the duration of eight machine instructions: the benefit of this approach is that other interrupts are
|
||||
virtually unaffected.
|
||||
|
||||
Interrupts and the REPL
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Interrupt handlers, such as those associated with timers, can continue to run
|
||||
after a program terminates. This may produce unexpected results where you might
|
||||
have expected the object raising the callback to have gone out of scope. For
|
||||
example on the Pyboard:
|
||||
|
||||
.. code:: python
|
||||
|
||||
def bar():
|
||||
foo = pyb.Timer(2, freq=4, callback=lambda t: print('.', end=''))
|
||||
|
||||
bar()
|
||||
|
||||
This continues to run until the timer is explicitly disabled or the board is
|
||||
reset with ``ctrl D``.
|
||||
|
||||
@@ -50,7 +50,7 @@ Finally type ``print(i)``, press RETURN, press BACKSPACE and press RETURN again:
|
||||
>>>
|
||||
|
||||
Auto-indent won't be applied if the previous two lines were all spaces. This
|
||||
means that you can finish entering a compound statment by pressing RETURN
|
||||
means that you can finish entering a compound statement by pressing RETURN
|
||||
twice, and then a third press will finish and execute.
|
||||
|
||||
Auto-completion
|
||||
@@ -80,7 +80,7 @@ expansions:
|
||||
Interrupting a running program
|
||||
------------------------------
|
||||
|
||||
You can interupt a running program by pressing Ctrl-C. This will raise a KeyboardInterrupt
|
||||
You can interrupt a running program by pressing Ctrl-C. This will raise a KeyboardInterrupt
|
||||
which will bring you back to the REPL, providing your program doesn't intercept the
|
||||
KeyboardInterrupt exception.
|
||||
|
||||
@@ -184,8 +184,8 @@ variables no longer exist:
|
||||
The special variable _ (underscore)
|
||||
-----------------------------------
|
||||
|
||||
When you use the REPL, you may perfom computations and see the results.
|
||||
MicroPython stores the results of the previous statment in the variable _ (underscore).
|
||||
When you use the REPL, you may perform computations and see the results.
|
||||
MicroPython stores the results of the previous statement in the variable _ (underscore).
|
||||
So you can use the underscore to save the result in a variable. For example:
|
||||
|
||||
>>> 1 + 2 + 3 + 4 + 5
|
||||
|
||||
@@ -16,7 +16,7 @@ Before applying power
|
||||
|
||||
.. warning::
|
||||
|
||||
The GPIO pins of the WiPy are NOT 5V tolerant, connecting them to voltages higer
|
||||
The GPIO pins of the WiPy are NOT 5V tolerant, connecting them to voltages higher
|
||||
than 3.6V will cause irreparable damage to the board. ADC pins, when configured
|
||||
in analog mode cannot withstand voltages above 1.8V. Keep these considerations in
|
||||
mind when wiring your electronics.
|
||||
|
||||
@@ -205,7 +205,7 @@ See :ref:`network.Server <network.Server>` ::
|
||||
server = Server(login=('user', 'password'), timeout=60)
|
||||
server.timeout(300) # change the timeout
|
||||
server.timeout() # get the timeout
|
||||
server.isrunning() # check wether the server is running or not
|
||||
server.isrunning() # check whether the server is running or not
|
||||
|
||||
Heart beat LED
|
||||
--------------
|
||||
|
||||
@@ -17,7 +17,7 @@ Because the WiPy/expansion board does not have a housing it needs a bit of care:
|
||||
If you experience a lot of static electricity in your area (eg dry and cold
|
||||
climates), take extra care not to shock the WiPy. If your WiPy came
|
||||
in a ESD bag, then this bag is the best way to store and carry the
|
||||
WiPy as it will protect it agains static discharges.
|
||||
WiPy as it will protect it against static discharges.
|
||||
|
||||
As long as you take care of the hardware, you should be okay. It's almost
|
||||
impossible to break the software on the WiPy, so feel free to play around
|
||||
|
||||
@@ -4,31 +4,41 @@ 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:
|
||||
Example usage on pyboard:
|
||||
|
||||
import pyb, sdcard, os
|
||||
sd = sdcard.SDCard(pyb.SPI(1), pyb.Pin.board.X5)
|
||||
pyb.mount(sd, '/sd2')
|
||||
os.listdir('/')
|
||||
|
||||
Example usage on ESP8266:
|
||||
|
||||
import machine, sdcard, os
|
||||
sd = sdcard.SDCard(machine.SPI(0), machine.Pin(15))
|
||||
os.umount()
|
||||
os.VfsFat(sd, "")
|
||||
os.listdir()
|
||||
|
||||
"""
|
||||
|
||||
import pyb
|
||||
import time
|
||||
|
||||
|
||||
_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)
|
||||
_TOKEN_CMD25 = const(0xfc)
|
||||
_TOKEN_STOP_TRAN = const(0xfd)
|
||||
_TOKEN_DATA = const(0xfe)
|
||||
|
||||
|
||||
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)
|
||||
TOKEN_CMD25 = const(0xfc)
|
||||
TOKEN_STOP_TRAN = const(0xfd)
|
||||
TOKEN_DATA = const(0xfe)
|
||||
|
||||
def __init__(self, spi, cs):
|
||||
self.spi = spi
|
||||
self.cs = cs
|
||||
@@ -42,30 +52,39 @@ class SDCard:
|
||||
# initialise the card
|
||||
self.init_card()
|
||||
|
||||
def init_spi(self, baudrate):
|
||||
try:
|
||||
master = self.spi.MASTER
|
||||
except AttributeError:
|
||||
# on ESP8266
|
||||
self.spi.init(baudrate=baudrate, phase=0, polarity=0)
|
||||
else:
|
||||
# on pyboard
|
||||
self.spi.init(master, baudrate=baudrate, phase=0, polarity=0)
|
||||
|
||||
def init_card(self):
|
||||
# init CS pin
|
||||
self.cs.high()
|
||||
self.cs.init(self.cs.OUT_PP)
|
||||
self.cs.init(self.cs.OUT, value=1)
|
||||
|
||||
# init SPI bus; use low data rate for initialisation
|
||||
self.spi.init(self.spi.MASTER, baudrate=100000, phase=0, polarity=0)
|
||||
self.init_spi(100000)
|
||||
|
||||
# clock card at least 100 cycles with cs high
|
||||
for i in range(16):
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
# CMD0: init card; should return R1_IDLE_STATE (allow 5 attempts)
|
||||
# CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
|
||||
for _ in range(5):
|
||||
if self.cmd(0, 0, 0x95) == R1_IDLE_STATE:
|
||||
if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
|
||||
break
|
||||
else:
|
||||
raise OSError("no SD card")
|
||||
|
||||
# CMD8: determine card version
|
||||
r = self.cmd(8, 0x01aa, 0x87, 4)
|
||||
if r == R1_IDLE_STATE:
|
||||
if r == _R1_IDLE_STATE:
|
||||
self.init_card_v2()
|
||||
elif r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND):
|
||||
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
|
||||
self.init_card_v1()
|
||||
else:
|
||||
raise OSError("couldn't determine SD card version")
|
||||
@@ -86,10 +105,10 @@ class SDCard:
|
||||
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)
|
||||
self.init_spi(1320000)
|
||||
|
||||
def init_card_v1(self):
|
||||
for i in range(CMD_TIMEOUT):
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0, 0) == 0:
|
||||
self.cdv = 512
|
||||
@@ -98,8 +117,8 @@ class SDCard:
|
||||
raise OSError("timeout waiting for v1 card")
|
||||
|
||||
def init_card_v2(self):
|
||||
for i in range(CMD_TIMEOUT):
|
||||
pyb.delay(50)
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
time.sleep_ms(50)
|
||||
self.cmd(58, 0, 0, 4)
|
||||
self.cmd(55, 0, 0)
|
||||
if self.cmd(41, 0x40000000, 0) == 0:
|
||||
@@ -120,87 +139,87 @@ class SDCard:
|
||||
buf[3] = arg >> 8
|
||||
buf[4] = arg
|
||||
buf[5] = crc
|
||||
self.spi.send(buf)
|
||||
self.spi.write(buf)
|
||||
|
||||
# wait for the repsonse (response[7] == 0)
|
||||
for i in range(CMD_TIMEOUT):
|
||||
response = self.spi.send_recv(0xff)[0]
|
||||
for i in range(_CMD_TIMEOUT):
|
||||
response = self.spi.read(1, 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)
|
||||
self.spi.write(b'\xff')
|
||||
if release:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return response
|
||||
|
||||
# timeout
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return -1
|
||||
|
||||
def cmd_nodata(self, cmd):
|
||||
self.spi.send(cmd)
|
||||
self.spi.send_recv(0xff) # ignore stuff byte
|
||||
for _ in range(CMD_TIMEOUT):
|
||||
if self.spi.send_recv(0xff)[0] == 0xff:
|
||||
self.spi.write(cmd)
|
||||
self.spi.read(1, 0xff) # ignore stuff byte
|
||||
for _ in range(_CMD_TIMEOUT):
|
||||
if self.spi.read(1, 0xff)[0] == 0xff:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return 0 # OK
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return 1 # timeout
|
||||
|
||||
def readinto(self, buf):
|
||||
self.cs.low()
|
||||
|
||||
# read until start byte (0xff)
|
||||
while self.spi.send_recv(0xff)[0] != 0xfe:
|
||||
while self.spi.read(1, 0xff)[0] != 0xfe:
|
||||
pass
|
||||
|
||||
# read data
|
||||
mv = self.dummybuf_memoryview[:len(buf)]
|
||||
self.spi.send_recv(mv, recv=buf)
|
||||
self.spi.write_readinto(mv, buf)
|
||||
|
||||
# read checksum
|
||||
self.spi.send(0xff)
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
def write(self, token, buf):
|
||||
self.cs.low()
|
||||
|
||||
# send: start of block, data, checksum
|
||||
self.spi.send(token)
|
||||
self.spi.send(buf)
|
||||
self.spi.send(0xff)
|
||||
self.spi.send(0xff)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(buf)
|
||||
self.spi.write(b'\xff')
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
# check the response
|
||||
if (self.spi.send_recv(0xff)[0] & 0x1f) != 0x05:
|
||||
if (self.spi.read(1, 0xff)[0] & 0x1f) != 0x05:
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
return
|
||||
|
||||
# wait for write to finish
|
||||
while self.spi.send_recv(0xff)[0] == 0:
|
||||
while self.spi.read(1, 0xff)[0] == 0:
|
||||
pass
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
def write_token(self, token):
|
||||
self.cs.low()
|
||||
self.spi.send(token)
|
||||
self.spi.send(0xff)
|
||||
self.spi.read(1, token)
|
||||
self.spi.write(b'\xff')
|
||||
# wait for write to finish
|
||||
while self.spi.send_recv(0xff)[0] == 0:
|
||||
while self.spi.read(1, 0xff)[0] == 0x00:
|
||||
pass
|
||||
|
||||
self.cs.high()
|
||||
self.spi.send(0xff)
|
||||
self.spi.write(b'\xff')
|
||||
|
||||
def count(self):
|
||||
return self.sectors
|
||||
@@ -224,7 +243,7 @@ class SDCard:
|
||||
self.readinto(mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
return self.cmd_nodata(12)
|
||||
return self.cmd_nodata(b'\x0c') # cmd 12
|
||||
return 0
|
||||
|
||||
def writeblocks(self, block_num, buf):
|
||||
@@ -236,7 +255,7 @@ class SDCard:
|
||||
return 1
|
||||
|
||||
# send the data
|
||||
self.write(TOKEN_DATA, buf)
|
||||
self.write(_TOKEN_DATA, buf)
|
||||
else:
|
||||
# CMD25: set write address for first block
|
||||
if self.cmd(25, block_num * self.cdv, 0) != 0:
|
||||
@@ -245,8 +264,8 @@ class SDCard:
|
||||
offset = 0
|
||||
mv = memoryview(buf)
|
||||
while nblocks:
|
||||
self.write(TOKEN_CMD25, mv[offset : offset + 512])
|
||||
self.write(_TOKEN_CMD25, mv[offset : offset + 512])
|
||||
offset += 512
|
||||
nblocks -= 1
|
||||
self.write_token(TOKEN_STOP_TRAN)
|
||||
self.write_token(_TOKEN_STOP_TRAN)
|
||||
return 0
|
||||
|
||||
@@ -157,7 +157,7 @@ int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8
|
||||
setSn_PORT(sn,port);
|
||||
setSn_CR(sn,Sn_CR_OPEN);
|
||||
while(getSn_CR(sn));
|
||||
sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
|
||||
sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
|
||||
sock_is_sending &= ~(1<<sn);
|
||||
sock_remained_size[sn] = 0;
|
||||
sock_pack_info[sn] = 0;
|
||||
|
||||
@@ -4,6 +4,8 @@ include ../py/mkenv.mk
|
||||
QSTR_DEFS = qstrdefsport.h #$(BUILD)/pins_qstr.h
|
||||
|
||||
MICROPY_PY_USSL = 1
|
||||
MICROPY_SSL_AXTLS = 1
|
||||
MICROPY_PY_BTREE = 1
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
@@ -76,7 +78,9 @@ SRC_C = \
|
||||
modpybrtc.c \
|
||||
modpybadc.c \
|
||||
modpybuart.c \
|
||||
modmachinewdt.c \
|
||||
modpybspi.c \
|
||||
modpybhspi.c \
|
||||
modesp.c \
|
||||
modnetwork.c \
|
||||
modutime.c \
|
||||
@@ -87,6 +91,8 @@ SRC_C = \
|
||||
$(BUILD)/frozen.c \
|
||||
fatfs_port.c \
|
||||
axtls_helpers.c \
|
||||
hspi.c \
|
||||
$(SRC_MOD)
|
||||
|
||||
STM_SRC_C = $(addprefix stmhal/,\
|
||||
pybstdio.c \
|
||||
@@ -122,7 +128,6 @@ LIB_SRC_C = $(addprefix lib/,\
|
||||
timeutils/timeutils.c \
|
||||
utils/pyexec.c \
|
||||
utils/pyhelp.c \
|
||||
utils/printf.c \
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
)
|
||||
@@ -134,7 +139,7 @@ DRIVERS_SRC_C = $(addprefix drivers/,\
|
||||
SRC_S = \
|
||||
gchelper.s \
|
||||
|
||||
FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR)/ -type f -name '*.py')
|
||||
FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py')
|
||||
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
|
||||
|
||||
OBJ =
|
||||
@@ -153,7 +158,7 @@ SRC_QSTR += $(SRC_C) $(STM_SRC_C) $(EXTMOD_SRC_C) $(DRIVERS_SRC_C)
|
||||
# Append any auto-generated sources that are needed by sources listed in SRC_QSTR
|
||||
SRC_QSTR_AUTO_DEPS +=
|
||||
|
||||
all: $(BUILD)/firmware-combined.bin
|
||||
all: $(BUILD)/libaxtls.a $(BUILD)/firmware-combined.bin
|
||||
|
||||
CONFVARS_FILE = $(BUILD)/confvars
|
||||
|
||||
@@ -229,8 +234,11 @@ $(BUILD)/firmware.elf: $(OBJ)
|
||||
|
||||
include ../py/mkrules.mk
|
||||
|
||||
axtls:
|
||||
axtls: $(BUILD)/libaxtls.a
|
||||
|
||||
$(BUILD)/libaxtls.a:
|
||||
cd ../lib/axtls; cp config/upyconfig config/.config
|
||||
cd ../lib/axtls; make oldconfig -B
|
||||
cd ../lib/axtls; make clean
|
||||
cd ../lib/axtls; make all CC="$(CC)" LD="$(LD)" AR="$(AR)" CFLAGS_EXTRA="$(CFLAGS_XTENSA) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=3072"
|
||||
cp ../lib/axtls/_stage/libaxtls.a $@
|
||||
|
||||
@@ -43,9 +43,6 @@ void *calloc(size_t nmemb, size_t size) {
|
||||
void *realloc(void *ptr, size_t size) {
|
||||
return gc_realloc(ptr, size, true);
|
||||
}
|
||||
void abort_(void) {
|
||||
printf("Aborted\n");
|
||||
}
|
||||
|
||||
#define PLATFORM_HTONL(_n) ((uint32_t)( (((_n) & 0xff) << 24) | (((_n) & 0xff00) << 8) | (((_n) >> 8) & 0xff00) | (((_n) >> 24) & 0xff) ))
|
||||
#undef htonl
|
||||
|
||||
@@ -20,6 +20,7 @@ PROVIDE ( SPI_read_status = 0x400043c8 );
|
||||
PROVIDE ( SPI_write_status = 0x40004400 );
|
||||
PROVIDE ( SPI_write_enable = 0x4000443c );
|
||||
PROVIDE ( Wait_SPI_Idle = 0x4000448c );
|
||||
PROVIDE ( Enable_QMode = 0x400044c0 );
|
||||
PROVIDE ( SPIEraseArea = 0x40004b44 );
|
||||
PROVIDE ( SPIEraseBlock = 0x400049b4 );
|
||||
PROVIDE ( SPIEraseChip = 0x40004984 );
|
||||
|
||||
@@ -5,7 +5,7 @@ MEMORY
|
||||
dport0_0_seg : org = 0x3ff00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3ffe8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40209000, len = 0x80000
|
||||
irom0_0_seg : org = 0x40209000, len = 0x87000
|
||||
}
|
||||
|
||||
/* define the top of RAM */
|
||||
@@ -121,6 +121,7 @@ SECTIONS
|
||||
|
||||
*lib/fatfs/*.o*(.literal*, .text*)
|
||||
*/libaxtls.a:(.literal*, .text*)
|
||||
*lib/berkeley-db-1.xx/*.o(.literal*, .text*)
|
||||
*lib/libm/*.o*(.literal*, .text*)
|
||||
*lib/mp-readline/*.o(.literal*, .text*)
|
||||
*lib/netutils/*.o*(.literal*, .text*)
|
||||
@@ -140,7 +141,10 @@ SECTIONS
|
||||
*modpybadc.o(.literal*, .text*)
|
||||
*modpybuart.o(.literal*, .text*)
|
||||
*modpybi2c.o(.literal*, .text*)
|
||||
*modmachinewdt.o(.literal*, .text*)
|
||||
*modpybspi.o(.literal*, .text*)
|
||||
*modpybhspi.o(.literal*, .text*)
|
||||
*hspi.o(.literal*, .text*)
|
||||
*modesp.o(.literal* .text*)
|
||||
*modnetwork.o(.literal* .text*)
|
||||
*moduos.o(.literal* .text*)
|
||||
|
||||
@@ -36,17 +36,13 @@
|
||||
#include "extmod/misc.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
|
||||
extern void ets_wdt_disable(void);
|
||||
extern void wdt_feed(void);
|
||||
extern void ets_delay_us();
|
||||
|
||||
STATIC byte input_buf_array[256];
|
||||
ringbuf_t input_buf = {input_buf_array, sizeof(input_buf_array)};
|
||||
void mp_hal_debug_tx_strn_cooked(void *env, const char *str, uint32_t len);
|
||||
const mp_print_t mp_debug_print = {NULL, mp_hal_debug_tx_strn_cooked};
|
||||
|
||||
void mp_hal_init(void) {
|
||||
ets_wdt_disable(); // it's a pain while developing
|
||||
//ets_wdt_disable(); // it's a pain while developing
|
||||
mp_hal_rtc_init();
|
||||
uart_init(UART_BIT_RATE_115200, UART_BIT_RATE_115200);
|
||||
}
|
||||
@@ -259,3 +255,8 @@ int ets_esf_free_bufs(int idx) {
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
extern int mp_stream_errno;
|
||||
int *__errno() {
|
||||
return &mp_stream_errno;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@ void mp_hal_init(void);
|
||||
void mp_hal_rtc_init(void);
|
||||
|
||||
uint32_t mp_hal_ticks_us(void);
|
||||
__attribute__((always_inline)) static inline uint32_t mp_hal_ticks_cpu(void) {
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||
return ccount;
|
||||
}
|
||||
|
||||
void mp_hal_delay_us(uint32_t);
|
||||
void mp_hal_set_interrupt_char(int c);
|
||||
uint32_t mp_hal_get_cpu_freq(void);
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if MICROPY_ESP8266_APA102
|
||||
|
||||
#include <stdio.h>
|
||||
#include "c_types.h"
|
||||
#include "eagle_soc.h"
|
||||
@@ -108,3 +111,5 @@ void esp_apa102_write(uint8_t clockPin, uint8_t dataPin, uint8_t *pixels, uint32
|
||||
_esp_apa102_append_additionial_cycles(clockPinMask, dataPinMask, numBytes);
|
||||
_esp_apa102_end_frame(clockPinMask, dataPinMask);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,16 +9,10 @@
|
||||
#include "eagle_soc.h"
|
||||
#include "user_interface.h"
|
||||
#include "espneopixel.h"
|
||||
#include "esp_mphal.h"
|
||||
|
||||
#define NEO_KHZ400 (1)
|
||||
|
||||
static uint32_t _getCycleCount(void) __attribute__((always_inline));
|
||||
static inline uint32_t _getCycleCount(void) {
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||
return ccount;
|
||||
}
|
||||
|
||||
void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32_t numBytes, bool is800KHz) {
|
||||
|
||||
uint8_t *p, *end, pix, mask;
|
||||
@@ -47,12 +41,13 @@ void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t irq_state = mp_hal_quiet_timing_enter();
|
||||
for(t = time0;; t = time0) {
|
||||
if(pix & mask) t = time1; // Bit high duration
|
||||
while(((c = _getCycleCount()) - startTime) < period); // Wait for bit start
|
||||
while(((c = mp_hal_ticks_cpu()) - startTime) < period); // Wait for bit start
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask); // Set high
|
||||
startTime = c; // Save start time
|
||||
while(((c = _getCycleCount()) - startTime) < t); // Wait high duration
|
||||
while(((c = mp_hal_ticks_cpu()) - startTime) < t); // Wait high duration
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask); // Set low
|
||||
if(!(mask >>= 1)) { // Next bit/byte
|
||||
if(p >= end) break;
|
||||
@@ -60,5 +55,6 @@ void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32
|
||||
mask = 0x80;
|
||||
}
|
||||
}
|
||||
while((_getCycleCount() - startTime) < period); // Wait for last bit
|
||||
while((mp_hal_ticks_cpu() - startTime) < period); // Wait for last bit
|
||||
mp_hal_quiet_timing_exit(irq_state);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,16 @@ void ets_timer_arm_new(os_timer_t *tim, uint32_t millis, bool repeat, bool is_mi
|
||||
void ets_timer_setfn(os_timer_t *tim, ETSTimerFunc callback, void *cb_data);
|
||||
void ets_timer_disarm(os_timer_t *tim);
|
||||
|
||||
extern void ets_wdt_disable(void);
|
||||
extern void wdt_feed(void);
|
||||
|
||||
// Opaque structure
|
||||
typedef char MD5_CTX[64];
|
||||
|
||||
void MD5Init(MD5_CTX *context);
|
||||
void MD5Update(MD5_CTX *context, const void *data, unsigned int len);
|
||||
void MD5Final(unsigned char digest[16], MD5_CTX *context);
|
||||
|
||||
// These prototypes are for recent SDKs with "malloc tracking"
|
||||
void *pvPortMalloc(unsigned sz, const char *fname, int line);
|
||||
void vPortFree(void *p, const char *fname, int line);
|
||||
|
||||
331
esp8266/hspi.c
Normal file
331
esp8266/hspi.c
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 David Ogilvy (MetalPhreak)
|
||||
* Modified 2016 by Radomir Dopieralski
|
||||
*
|
||||
* 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 "hspi.h"
|
||||
|
||||
/*
|
||||
Wrapper to setup HSPI/SPI GPIO pins and default SPI clock
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
Not used in Micropython.
|
||||
*/
|
||||
void spi_init(uint8_t spi_no) {
|
||||
spi_init_gpio(spi_no, SPI_CLK_USE_DIV);
|
||||
spi_clock(spi_no, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
|
||||
spi_tx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
spi_rx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Configures SPI mode parameters for clock edge and clock polarity.
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
spi_cpha - (0) Data is valid on clock leading edge
|
||||
(1) Data is valid on clock trailing edge
|
||||
spi_cpol - (0) Clock is low when inactive
|
||||
(1) Clock is high when inactive
|
||||
For Micropython this version is different from original.
|
||||
*/
|
||||
void spi_mode(uint8_t spi_no, uint8_t spi_cpha, uint8_t spi_cpol) {
|
||||
if (spi_cpol) {
|
||||
SET_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
|
||||
}
|
||||
if (spi_cpha == spi_cpol) {
|
||||
// Mode 3 - MOSI is set on falling edge of clock
|
||||
// Mode 0 - MOSI is set on falling edge of clock
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
|
||||
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
|
||||
} else {
|
||||
// Mode 2 - MOSI is set on rising edge of clock
|
||||
// Mode 1 - MOSI is set on rising edge of clock
|
||||
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialise the GPIO pins for use as SPI pins.
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
sysclk_as_spiclk -
|
||||
SPI_CLK_80MHZ_NODIV (1) if using 80MHz for SPI clock.
|
||||
SPI_CLK_USE_DIV (0) if using divider for lower speed.
|
||||
*/
|
||||
void spi_init_gpio(uint8_t spi_no, uint8_t sysclk_as_spiclk) {
|
||||
uint32_t clock_div_flag = 0;
|
||||
if (sysclk_as_spiclk) {
|
||||
clock_div_flag = 0x0001;
|
||||
}
|
||||
if (spi_no == SPI) {
|
||||
// Set bit 8 if 80MHz sysclock required
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div_flag<<8));
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);
|
||||
} else if (spi_no == HSPI) {
|
||||
// Set bit 9 if 80MHz sysclock required
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag<<9));
|
||||
// GPIO12 is HSPI MISO pin (Master Data In)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);
|
||||
// GPIO13 is HSPI MOSI pin (Master Data Out)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);
|
||||
// GPIO14 is HSPI CLK pin (Clock)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
|
||||
// GPIO15 is HSPI CS pin (Chip Select / Slave Select)
|
||||
// In Micropython, we are handling CS ourself in drivers.
|
||||
// PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set up the control registers for the SPI clock
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
prediv - predivider value (actual division value)
|
||||
cntdiv - postdivider value (actual division value)
|
||||
Set either divider to 0 to disable all division (80MHz sysclock)
|
||||
*/
|
||||
void spi_clock(uint8_t spi_no, uint16_t prediv, uint8_t cntdiv) {
|
||||
if (prediv == 0 || cntdiv == 0) {
|
||||
WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK);
|
||||
} else {
|
||||
WRITE_PERI_REG(SPI_CLOCK(spi_no),
|
||||
(((prediv - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
|
||||
(((cntdiv - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
|
||||
(((cntdiv >> 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
|
||||
((0 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Setup the byte order for shifting data out of buffer
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
byte_order -
|
||||
SPI_BYTE_ORDER_HIGH_TO_LOW (1)
|
||||
Data is sent out starting with Bit31 and down to Bit0
|
||||
SPI_BYTE_ORDER_LOW_TO_HIGH (0)
|
||||
Data is sent out starting with the lowest BYTE, from MSB to LSB,
|
||||
followed by the second lowest BYTE, from MSB to LSB, followed by
|
||||
the second highest BYTE, from MSB to LSB, followed by the highest
|
||||
BYTE, from MSB to LSB 0xABCDEFGH would be sent as 0xGHEFCDAB.
|
||||
*/
|
||||
void spi_tx_byte_order(uint8_t spi_no, uint8_t byte_order) {
|
||||
if (byte_order) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Setup the byte order for shifting data into buffer
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
byte_order -
|
||||
SPI_BYTE_ORDER_HIGH_TO_LOW (1)
|
||||
Data is read in starting with Bit31 and down to Bit0
|
||||
SPI_BYTE_ORDER_LOW_TO_HIGH (0)
|
||||
Data is read in starting with the lowest BYTE, from MSB to LSB,
|
||||
followed by the second lowest BYTE, from MSB to LSB, followed by
|
||||
the second highest BYTE, from MSB to LSB, followed by the highest
|
||||
BYTE, from MSB to LSB 0xABCDEFGH would be read as 0xGHEFCDAB
|
||||
*/
|
||||
void spi_rx_byte_order(uint8_t spi_no, uint8_t byte_order) {
|
||||
if (byte_order) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
SPI transaction function
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
cmd_bits - actual number of bits to transmit
|
||||
cmd_data - command data
|
||||
addr_bits - actual number of bits to transmit
|
||||
addr_data - address data
|
||||
dout_bits - actual number of bits to transmit
|
||||
dout_data - output data
|
||||
din_bits - actual number of bits to receive
|
||||
Returns: read data - uint32_t containing read in data only if RX was set
|
||||
0 - something went wrong (or actual read data was 0)
|
||||
1 - data sent ok (or actual read data is 1)
|
||||
Note: all data is assumed to be stored in the lower bits of the data variables
|
||||
(for anything <32 bits).
|
||||
*/
|
||||
uint32_t spi_transaction(uint8_t spi_no, uint8_t cmd_bits, uint16_t cmd_data,
|
||||
uint32_t addr_bits, uint32_t addr_data,
|
||||
uint32_t dout_bits, uint32_t dout_data,
|
||||
uint32_t din_bits, uint32_t dummy_bits) {
|
||||
while (spi_busy(spi_no)) {}; // Wait for SPI to be ready
|
||||
|
||||
// Enable SPI Functions
|
||||
// Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
|
||||
SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
|
||||
|
||||
// Enable functions based on number of bits. 0 bits = disabled.
|
||||
// This is rather inefficient but allows for a very generic function.
|
||||
// CMD ADDR and MOSI are set below to save on an extra if statement.
|
||||
if (din_bits) {
|
||||
if (dout_bits) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
|
||||
}
|
||||
}
|
||||
if (dummy_bits) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_DUMMY);
|
||||
}
|
||||
|
||||
// Setup Bitlengths
|
||||
WRITE_PERI_REG(SPI_USER1(spi_no),
|
||||
// Number of bits in Address
|
||||
((addr_bits - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S |
|
||||
// Number of bits to Send
|
||||
((dout_bits - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
|
||||
// Number of bits to receive
|
||||
((din_bits - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S |
|
||||
// Number of Dummy bits to insert
|
||||
((dummy_bits - 1) & SPI_USR_DUMMY_CYCLELEN) << SPI_USR_DUMMY_CYCLELEN_S);
|
||||
|
||||
// Setup Command Data
|
||||
if (cmd_bits) {
|
||||
// Enable COMMAND function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_COMMAND);
|
||||
// Align command data to high bits
|
||||
uint16_t command = cmd_data << (16-cmd_bits);
|
||||
// Swap byte order
|
||||
command = ((command>>8)&0xff) | ((command<<8)&0xff00);
|
||||
WRITE_PERI_REG(SPI_USER2(spi_no), (
|
||||
(((cmd_bits - 1) & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) |
|
||||
(command & SPI_USR_COMMAND_VALUE)
|
||||
));
|
||||
}
|
||||
|
||||
// Setup Address Data
|
||||
if (addr_bits) {
|
||||
// Enable ADDRess function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_ADDR);
|
||||
// Align address data to high bits
|
||||
WRITE_PERI_REG(SPI_ADDR(spi_no), addr_data << (32 - addr_bits));
|
||||
}
|
||||
|
||||
// Setup DOUT data
|
||||
if (dout_bits) {
|
||||
// Enable MOSI function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
|
||||
// Copy data to W0
|
||||
if (READ_PERI_REG(SPI_USER(spi_no))&SPI_WR_BYTE_ORDER) {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - dout_bits));
|
||||
} else {
|
||||
uint8_t dout_extra_bits = dout_bits%8;
|
||||
|
||||
if (dout_extra_bits) {
|
||||
// If your data isn't a byte multiple (8/16/24/32 bits) and you
|
||||
// don't have SPI_WR_BYTE_ORDER set, you need this to move the
|
||||
// non-8bit remainder to the MSBs. Not sure if there's even a use
|
||||
// case for this, but it's here if you need it... For example,
|
||||
// 0xDA4 12 bits without SPI_WR_BYTE_ORDER would usually be output
|
||||
// as if it were 0x0DA4, of which 0xA4, and then 0x0 would be
|
||||
// shifted out (first 8 bits of low byte, then 4 MSB bits of high
|
||||
// byte - ie reverse byte order).
|
||||
// The code below shifts it out as 0xA4 followed by 0xD as you
|
||||
// might require.
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), (
|
||||
(0xFFFFFFFF << (dout_bits - dout_extra_bits) & dout_data)
|
||||
<< (8-dout_extra_bits) |
|
||||
((0xFFFFFFFF >> (32 - (dout_bits - dout_extra_bits)))
|
||||
& dout_data)
|
||||
));
|
||||
} else {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Begin SPI Transaction
|
||||
SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
|
||||
|
||||
// Return DIN data
|
||||
if (din_bits) {
|
||||
while (spi_busy(spi_no)) {}; // Wait for SPI transaction to complete
|
||||
if (READ_PERI_REG(SPI_USER(spi_no))&SPI_RD_BYTE_ORDER) {
|
||||
// Assuming data in is written to MSB. TBC
|
||||
return READ_PERI_REG(SPI_W0(spi_no)) >> (32 - din_bits);
|
||||
} else {
|
||||
// Read in the same way as DOUT is sent. Note existing contents of
|
||||
// SPI_W0 remain unless overwritten!
|
||||
return READ_PERI_REG(SPI_W0(spi_no));
|
||||
}
|
||||
return 0; // Something went wrong
|
||||
}
|
||||
|
||||
// Transaction completed
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Just do minimal work needed to send 8 bits.
|
||||
*/
|
||||
inline void spi_tx8fast(uint8_t spi_no, uint8_t dout_data) {
|
||||
while (spi_busy(spi_no)) {}; // Wait for SPI to be ready
|
||||
|
||||
// Enable SPI Functions
|
||||
// Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
|
||||
SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
|
||||
|
||||
// Setup Bitlengths
|
||||
WRITE_PERI_REG(SPI_USER1(spi_no),
|
||||
// Number of bits to Send
|
||||
((8 - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
|
||||
// Number of bits to receive
|
||||
((8 - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S);
|
||||
|
||||
|
||||
// Setup DOUT data
|
||||
// Enable MOSI function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
|
||||
// Copy data to W0
|
||||
if (READ_PERI_REG(SPI_USER(spi_no)) & SPI_WR_BYTE_ORDER) {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - 8));
|
||||
} else {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
|
||||
}
|
||||
|
||||
// Begin SPI Transaction
|
||||
SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
|
||||
}
|
||||
79
esp8266/hspi.h
Normal file
79
esp8266/hspi.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 David Ogilvy (MetalPhreak)
|
||||
* Modified 2016 by Radomir Dopieralski
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SPI_APP_H
|
||||
#define SPI_APP_H
|
||||
|
||||
#include "hspi_register.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
|
||||
// Define SPI hardware modules
|
||||
#define SPI 0
|
||||
#define HSPI 1
|
||||
|
||||
#define SPI_CLK_USE_DIV 0
|
||||
#define SPI_CLK_80MHZ_NODIV 1
|
||||
|
||||
#define SPI_BYTE_ORDER_HIGH_TO_LOW 1
|
||||
#define SPI_BYTE_ORDER_LOW_TO_HIGH 0
|
||||
|
||||
#ifndef CPU_CLK_FREQ //Should already be defined in eagle_soc.h
|
||||
#define CPU_CLK_FREQ (80 * 1000000)
|
||||
#endif
|
||||
|
||||
// Define some default SPI clock settings
|
||||
#define SPI_CLK_PREDIV 10
|
||||
#define SPI_CLK_CNTDIV 2
|
||||
#define SPI_CLK_FREQ (CPU_CLK_FREQ / (SPI_CLK_PREDIV * SPI_CLK_CNTDIV))
|
||||
// 80 / 20 = 4 MHz
|
||||
|
||||
void spi_init(uint8_t spi_no);
|
||||
void spi_mode(uint8_t spi_no, uint8_t spi_cpha,uint8_t spi_cpol);
|
||||
void spi_init_gpio(uint8_t spi_no, uint8_t sysclk_as_spiclk);
|
||||
void spi_clock(uint8_t spi_no, uint16_t prediv, uint8_t cntdiv);
|
||||
void spi_tx_byte_order(uint8_t spi_no, uint8_t byte_order);
|
||||
void spi_rx_byte_order(uint8_t spi_no, uint8_t byte_order);
|
||||
uint32_t spi_transaction(uint8_t spi_no, uint8_t cmd_bits, uint16_t cmd_data,
|
||||
uint32_t addr_bits, uint32_t addr_data,
|
||||
uint32_t dout_bits, uint32_t dout_data,
|
||||
uint32_t din_bits, uint32_t dummy_bits);
|
||||
void spi_tx8fast(uint8_t spi_no, uint8_t dout_data);
|
||||
|
||||
// Expansion Macros
|
||||
#define spi_busy(spi_no) READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR
|
||||
|
||||
#define spi_txd(spi_no, bits, data) spi_transaction(spi_no, 0, 0, 0, 0, bits, (uint32_t) data, 0, 0)
|
||||
#define spi_tx8(spi_no, data) spi_transaction(spi_no, 0, 0, 0, 0, 8, (uint32_t) data, 0, 0)
|
||||
#define spi_tx16(spi_no, data) spi_transaction(spi_no, 0, 0, 0, 0, 16, (uint32_t) data, 0, 0)
|
||||
#define spi_tx32(spi_no, data) spi_transaction(spi_no, 0, 0, 0, 0, 32, (uint32_t) data, 0, 0)
|
||||
|
||||
#define spi_rxd(spi_no, bits) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, bits, 0)
|
||||
#define spi_rx8(spi_no) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 8, 0)
|
||||
#define spi_rx16(spi_no) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 16, 0)
|
||||
#define spi_rx32(spi_no) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 32, 0)
|
||||
|
||||
#endif
|
||||
278
esp8266/hspi_register.h
Normal file
278
esp8266/hspi_register.h
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2010 - 2011 Espressif System
|
||||
* Modified by David Ogilvy (MetalPhreak)
|
||||
* Based on original file included in SDK 1.0.0
|
||||
*
|
||||
* Missing defines from previous SDK versions have
|
||||
* been added and are noted with comments. The
|
||||
* names of these defines are likely to change.
|
||||
*/
|
||||
|
||||
#ifndef SPI_REGISTER_H_INCLUDED
|
||||
#define SPI_REGISTER_H_INCLUDED
|
||||
|
||||
#define REG_SPI_BASE(i) (0x60000200-i*0x100)
|
||||
|
||||
#define SPI_CMD(i) (REG_SPI_BASE(i) + 0x0)
|
||||
#define SPI_FLASH_READ (BIT(31)) //From previous SDK
|
||||
#define SPI_FLASH_WREN (BIT(30)) //From previous SDK
|
||||
#define SPI_FLASH_WRDI (BIT(29)) //From previous SDK
|
||||
#define SPI_FLASH_RDID (BIT(28)) //From previous SDK
|
||||
#define SPI_FLASH_RDSR (BIT(27)) //From previous SDK
|
||||
#define SPI_FLASH_WRSR (BIT(26)) //From previous SDK
|
||||
#define SPI_FLASH_PP (BIT(25)) //From previous SDK
|
||||
#define SPI_FLASH_SE (BIT(24)) //From previous SDK
|
||||
#define SPI_FLASH_BE (BIT(23)) //From previous SDK
|
||||
#define SPI_FLASH_CE (BIT(22)) //From previous SDK
|
||||
#define SPI_FLASH_DP (BIT(21)) //From previous SDK
|
||||
#define SPI_FLASH_RES (BIT(20)) //From previous SDK
|
||||
#define SPI_FLASH_HPM (BIT(19)) //From previous SDK
|
||||
#define SPI_USR (BIT(18))
|
||||
|
||||
#define SPI_ADDR(i) (REG_SPI_BASE(i) + 0x4)
|
||||
|
||||
#define SPI_CTRL(i) (REG_SPI_BASE(i) + 0x8)
|
||||
#define SPI_WR_BIT_ORDER (BIT(26))
|
||||
#define SPI_RD_BIT_ORDER (BIT(25))
|
||||
#define SPI_QIO_MODE (BIT(24))
|
||||
#define SPI_DIO_MODE (BIT(23))
|
||||
#define SPI_TWO_BYTE_STATUS_EN (BIT(22)) //From previous SDK
|
||||
#define SPI_WP_REG (BIT(21)) //From previous SDK
|
||||
#define SPI_QOUT_MODE (BIT(20))
|
||||
#define SPI_SHARE_BUS (BIT(19)) //From previous SDK
|
||||
#define SPI_HOLD_MODE (BIT(18)) //From previous SDK
|
||||
#define SPI_ENABLE_AHB (BIT(17)) //From previous SDK
|
||||
#define SPI_SST_AAI (BIT(16)) //From previous SDK
|
||||
#define SPI_RESANDRES (BIT(15)) //From previous SDK
|
||||
#define SPI_DOUT_MODE (BIT(14))
|
||||
#define SPI_FASTRD_MODE (BIT(13))
|
||||
|
||||
#define SPI_CTRL1(i) (REG_SPI_BASE (i) + 0xC) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_CS_HOLD_DELAY 0x0000000F //Espressif BBS
|
||||
#define SPI_CS_HOLD_DELAY_S 28 //Espressif BBS
|
||||
#define SPI_CS_HOLD_DELAY_RES 0x00000FFF //Espressif BBS
|
||||
#define SPI_CS_HOLD_DELAY_RES_S 16 //Espressif BBS
|
||||
#define SPI_BUS_TIMER_LIMIT 0x0000FFFF //From previous SDK
|
||||
#define SPI_BUS_TIMER_LIMIT_S 0 //From previous SDK
|
||||
|
||||
|
||||
#define SPI_RD_STATUS(i) (REG_SPI_BASE(i) + 0x10)
|
||||
#define SPI_STATUS_EXT 0x000000FF //From previous SDK
|
||||
#define SPI_STATUS_EXT_S 24 //From previous SDK
|
||||
#define SPI_WB_MODE 0x000000FF //From previous SDK
|
||||
#define SPI_WB_MODE_S 16 //From previous SDK
|
||||
#define SPI_FLASH_STATUS_PRO_FLAG (BIT(7)) //From previous SDK
|
||||
#define SPI_FLASH_TOP_BOT_PRO_FLAG (BIT(5)) //From previous SDK
|
||||
#define SPI_FLASH_BP2 (BIT(4)) //From previous SDK
|
||||
#define SPI_FLASH_BP1 (BIT(3)) //From previous SDK
|
||||
#define SPI_FLASH_BP0 (BIT(2)) //From previous SDK
|
||||
#define SPI_FLASH_WRENABLE_FLAG (BIT(1)) //From previous SDK
|
||||
#define SPI_FLASH_BUSY_FLAG (BIT(0)) //From previous SDK
|
||||
|
||||
#define SPI_CTRL2(i) (REG_SPI_BASE(i) + 0x14)
|
||||
#define SPI_CS_DELAY_NUM 0x0000000F
|
||||
#define SPI_CS_DELAY_NUM_S 28
|
||||
#define SPI_CS_DELAY_MODE 0x00000003
|
||||
#define SPI_CS_DELAY_MODE_S 26
|
||||
#define SPI_MOSI_DELAY_NUM 0x00000007
|
||||
#define SPI_MOSI_DELAY_NUM_S 23
|
||||
#define SPI_MOSI_DELAY_MODE 0x00000003 //mode 0 : posedge; data set at positive edge of clk
|
||||
//mode 1 : negedge + 1 cycle delay, only if freq<10MHz ; data set at negitive edge of clk
|
||||
//mode 2 : Do not use this mode.
|
||||
#define SPI_MOSI_DELAY_MODE_S 21
|
||||
#define SPI_MISO_DELAY_NUM 0x00000007
|
||||
#define SPI_MISO_DELAY_NUM_S 18
|
||||
#define SPI_MISO_DELAY_MODE 0x00000003
|
||||
#define SPI_MISO_DELAY_MODE_S 16
|
||||
#define SPI_CK_OUT_HIGH_MODE 0x0000000F
|
||||
#define SPI_CK_OUT_HIGH_MODE_S 12
|
||||
#define SPI_CK_OUT_LOW_MODE 0x0000000F
|
||||
#define SPI_CK_OUT_LOW_MODE_S 8
|
||||
#define SPI_HOLD_TIME 0x0000000F
|
||||
#define SPI_HOLD_TIME_S 4
|
||||
#define SPI_SETUP_TIME 0x0000000F
|
||||
#define SPI_SETUP_TIME_S 0
|
||||
|
||||
#define SPI_CLOCK(i) (REG_SPI_BASE(i) + 0x18)
|
||||
#define SPI_CLK_EQU_SYSCLK (BIT(31))
|
||||
#define SPI_CLKDIV_PRE 0x00001FFF
|
||||
#define SPI_CLKDIV_PRE_S 18
|
||||
#define SPI_CLKCNT_N 0x0000003F
|
||||
#define SPI_CLKCNT_N_S 12
|
||||
#define SPI_CLKCNT_H 0x0000003F
|
||||
#define SPI_CLKCNT_H_S 6
|
||||
#define SPI_CLKCNT_L 0x0000003F
|
||||
#define SPI_CLKCNT_L_S 0
|
||||
|
||||
#define SPI_USER(i) (REG_SPI_BASE(i) + 0x1C)
|
||||
#define SPI_USR_COMMAND (BIT(31))
|
||||
#define SPI_USR_ADDR (BIT(30))
|
||||
#define SPI_USR_DUMMY (BIT(29))
|
||||
#define SPI_USR_MISO (BIT(28))
|
||||
#define SPI_USR_MOSI (BIT(27))
|
||||
#define SPI_USR_DUMMY_IDLE (BIT(26)) //From previous SDK
|
||||
#define SPI_USR_MOSI_HIGHPART (BIT(25))
|
||||
#define SPI_USR_MISO_HIGHPART (BIT(24))
|
||||
#define SPI_USR_PREP_HOLD (BIT(23)) //From previous SDK
|
||||
#define SPI_USR_CMD_HOLD (BIT(22)) //From previous SDK
|
||||
#define SPI_USR_ADDR_HOLD (BIT(21)) //From previous SDK
|
||||
#define SPI_USR_DUMMY_HOLD (BIT(20)) //From previous SDK
|
||||
#define SPI_USR_DIN_HOLD (BIT(19)) //From previous SDK
|
||||
#define SPI_USR_DOUT_HOLD (BIT(18)) //From previous SDK
|
||||
#define SPI_USR_HOLD_POL (BIT(17)) //From previous SDK
|
||||
#define SPI_SIO (BIT(16))
|
||||
#define SPI_FWRITE_QIO (BIT(15))
|
||||
#define SPI_FWRITE_DIO (BIT(14))
|
||||
#define SPI_FWRITE_QUAD (BIT(13))
|
||||
#define SPI_FWRITE_DUAL (BIT(12))
|
||||
#define SPI_WR_BYTE_ORDER (BIT(11))
|
||||
#define SPI_RD_BYTE_ORDER (BIT(10))
|
||||
#define SPI_AHB_ENDIAN_MODE 0x00000003 //From previous SDK
|
||||
#define SPI_AHB_ENDIAN_MODE_S 8 //From previous SDK
|
||||
#define SPI_CK_OUT_EDGE (BIT(7))
|
||||
#define SPI_CK_I_EDGE (BIT(6))
|
||||
#define SPI_CS_SETUP (BIT(5))
|
||||
#define SPI_CS_HOLD (BIT(4))
|
||||
#define SPI_AHB_USR_COMMAND (BIT(3)) //From previous SDK
|
||||
#define SPI_FLASH_MODE (BIT(2))
|
||||
#define SPI_AHB_USR_COMMAND_4BYTE (BIT(1)) //From previous SDK
|
||||
#define SPI_DOUTDIN (BIT(0)) //From previous SDK
|
||||
|
||||
//AHB = http://en.wikipedia.org/wiki/Advanced_Microcontroller_Bus_Architecture ?
|
||||
|
||||
|
||||
#define SPI_USER1(i) (REG_SPI_BASE(i) + 0x20)
|
||||
#define SPI_USR_ADDR_BITLEN 0x0000003F
|
||||
#define SPI_USR_ADDR_BITLEN_S 26
|
||||
#define SPI_USR_MOSI_BITLEN 0x000001FF
|
||||
#define SPI_USR_MOSI_BITLEN_S 17
|
||||
#define SPI_USR_MISO_BITLEN 0x000001FF
|
||||
#define SPI_USR_MISO_BITLEN_S 8
|
||||
#define SPI_USR_DUMMY_CYCLELEN 0x000000FF
|
||||
#define SPI_USR_DUMMY_CYCLELEN_S 0
|
||||
|
||||
#define SPI_USER2(i) (REG_SPI_BASE(i) + 0x24)
|
||||
#define SPI_USR_COMMAND_BITLEN 0x0000000F
|
||||
#define SPI_USR_COMMAND_BITLEN_S 28
|
||||
#define SPI_USR_COMMAND_VALUE 0x0000FFFF
|
||||
#define SPI_USR_COMMAND_VALUE_S 0
|
||||
|
||||
#define SPI_WR_STATUS(i) (REG_SPI_BASE(i) + 0x28)
|
||||
//previously defined as SPI_FLASH_USER3. No further info available.
|
||||
|
||||
#define SPI_PIN(i) (REG_SPI_BASE(i) + 0x2C)
|
||||
#define SPI_IDLE_EDGE (BIT(29))
|
||||
#define SPI_CS2_DIS (BIT(2))
|
||||
#define SPI_CS1_DIS (BIT(1))
|
||||
#define SPI_CS0_DIS (BIT(0))
|
||||
|
||||
#define SPI_SLAVE(i) (REG_SPI_BASE(i) + 0x30)
|
||||
#define SPI_SYNC_RESET (BIT(31))
|
||||
#define SPI_SLAVE_MODE (BIT(30))
|
||||
#define SPI_SLV_WR_RD_BUF_EN (BIT(29))
|
||||
#define SPI_SLV_WR_RD_STA_EN (BIT(28))
|
||||
#define SPI_SLV_CMD_DEFINE (BIT(27))
|
||||
#define SPI_TRANS_CNT 0x0000000F
|
||||
#define SPI_TRANS_CNT_S 23
|
||||
#define SPI_SLV_LAST_STATE 0x00000007 //From previous SDK
|
||||
#define SPI_SLV_LAST_STATE_S 20 //From previous SDK
|
||||
#define SPI_SLV_LAST_COMMAND 0x00000007 //From previous SDK
|
||||
#define SPI_SLV_LAST_COMMAND_S 17 //From previous SDK
|
||||
#define SPI_CS_I_MODE 0x00000003 //From previous SDK
|
||||
#define SPI_CS_I_MODE_S 10 //From previous SDK
|
||||
#define SPI_TRANS_DONE_EN (BIT(9))
|
||||
#define SPI_SLV_WR_STA_DONE_EN (BIT(8))
|
||||
#define SPI_SLV_RD_STA_DONE_EN (BIT(7))
|
||||
#define SPI_SLV_WR_BUF_DONE_EN (BIT(6))
|
||||
#define SPI_SLV_RD_BUF_DONE_EN (BIT(5))
|
||||
#define SLV_SPI_INT_EN 0x0000001f
|
||||
#define SLV_SPI_INT_EN_S 5
|
||||
#define SPI_TRANS_DONE (BIT(4))
|
||||
#define SPI_SLV_WR_STA_DONE (BIT(3))
|
||||
#define SPI_SLV_RD_STA_DONE (BIT(2))
|
||||
#define SPI_SLV_WR_BUF_DONE (BIT(1))
|
||||
#define SPI_SLV_RD_BUF_DONE (BIT(0))
|
||||
|
||||
#define SPI_SLAVE1(i) (REG_SPI_BASE(i) + 0x34)
|
||||
#define SPI_SLV_STATUS_BITLEN 0x0000001F
|
||||
#define SPI_SLV_STATUS_BITLEN_S 27
|
||||
#define SPI_SLV_STATUS_FAST_EN (BIT(26)) //From previous SDK
|
||||
#define SPI_SLV_STATUS_READBACK (BIT(25)) //From previous SDK
|
||||
#define SPI_SLV_BUF_BITLEN 0x000001FF
|
||||
#define SPI_SLV_BUF_BITLEN_S 16
|
||||
#define SPI_SLV_RD_ADDR_BITLEN 0x0000003F
|
||||
#define SPI_SLV_RD_ADDR_BITLEN_S 10
|
||||
#define SPI_SLV_WR_ADDR_BITLEN 0x0000003F
|
||||
#define SPI_SLV_WR_ADDR_BITLEN_S 4
|
||||
#define SPI_SLV_WRSTA_DUMMY_EN (BIT(3))
|
||||
#define SPI_SLV_RDSTA_DUMMY_EN (BIT(2))
|
||||
#define SPI_SLV_WRBUF_DUMMY_EN (BIT(1))
|
||||
#define SPI_SLV_RDBUF_DUMMY_EN (BIT(0))
|
||||
|
||||
|
||||
|
||||
#define SPI_SLAVE2(i) (REG_SPI_BASE(i) + 0x38)
|
||||
#define SPI_SLV_WRBUF_DUMMY_CYCLELEN 0X000000FF
|
||||
#define SPI_SLV_WRBUF_DUMMY_CYCLELEN_S 24
|
||||
#define SPI_SLV_RDBUF_DUMMY_CYCLELEN 0X000000FF
|
||||
#define SPI_SLV_RDBUF_DUMMY_CYCLELEN_S 16
|
||||
#define SPI_SLV_WRSTR_DUMMY_CYCLELEN 0X000000FF
|
||||
#define SPI_SLV_WRSTR_DUMMY_CYCLELEN_S 8
|
||||
#define SPI_SLV_RDSTR_DUMMY_CYCLELEN 0x000000FF
|
||||
#define SPI_SLV_RDSTR_DUMMY_CYCLELEN_S 0
|
||||
|
||||
#define SPI_SLAVE3(i) (REG_SPI_BASE(i) + 0x3C)
|
||||
#define SPI_SLV_WRSTA_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_WRSTA_CMD_VALUE_S 24
|
||||
#define SPI_SLV_RDSTA_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_RDSTA_CMD_VALUE_S 16
|
||||
#define SPI_SLV_WRBUF_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_WRBUF_CMD_VALUE_S 8
|
||||
#define SPI_SLV_RDBUF_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_RDBUF_CMD_VALUE_S 0
|
||||
|
||||
//Previous SDKs referred to these following registers as SPI_C0 etc.
|
||||
|
||||
#define SPI_W0(i) (REG_SPI_BASE(i) +0x40)
|
||||
#define SPI_W1(i) (REG_SPI_BASE(i) +0x44)
|
||||
#define SPI_W2(i) (REG_SPI_BASE(i) +0x48)
|
||||
#define SPI_W3(i) (REG_SPI_BASE(i) +0x4C)
|
||||
#define SPI_W4(i) (REG_SPI_BASE(i) +0x50)
|
||||
#define SPI_W5(i) (REG_SPI_BASE(i) +0x54)
|
||||
#define SPI_W6(i) (REG_SPI_BASE(i) +0x58)
|
||||
#define SPI_W7(i) (REG_SPI_BASE(i) +0x5C)
|
||||
#define SPI_W8(i) (REG_SPI_BASE(i) +0x60)
|
||||
#define SPI_W9(i) (REG_SPI_BASE(i) +0x64)
|
||||
#define SPI_W10(i) (REG_SPI_BASE(i) +0x68)
|
||||
#define SPI_W11(i) (REG_SPI_BASE(i) +0x6C)
|
||||
#define SPI_W12(i) (REG_SPI_BASE(i) +0x70)
|
||||
#define SPI_W13(i) (REG_SPI_BASE(i) +0x74)
|
||||
#define SPI_W14(i) (REG_SPI_BASE(i) +0x78)
|
||||
#define SPI_W15(i) (REG_SPI_BASE(i) +0x7C)
|
||||
|
||||
// +0x80 to +0xBC could be SPI_W16 through SPI_W31?
|
||||
|
||||
// +0xC0 to +0xEC not currently defined.
|
||||
|
||||
#define SPI_EXT0(i) (REG_SPI_BASE(i) + 0xF0) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_T_PP_ENA (BIT(31)) //From previous SDK
|
||||
#define SPI_T_PP_SHIFT 0x0000000F //From previous SDK
|
||||
#define SPI_T_PP_SHIFT_S 16 //From previous SDK
|
||||
#define SPI_T_PP_TIME 0x00000FFF //From previous SDK
|
||||
#define SPI_T_PP_TIME_S 0 //From previous SDK
|
||||
|
||||
#define SPI_EXT1(i) (REG_SPI_BASE(i) + 0xF4) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_T_ERASE_ENA (BIT(31)) //From previous SDK
|
||||
#define SPI_T_ERASE_SHIFT 0x0000000F //From previous SDK
|
||||
#define SPI_T_ERASE_SHIFT_S 16 //From previous SDK
|
||||
#define SPI_T_ERASE_TIME 0x00000FFF //From previous SDK
|
||||
#define SPI_T_ERASE_TIME_S 0 //From previous SDK
|
||||
|
||||
#define SPI_EXT2(i) (REG_SPI_BASE(i) + 0xF8) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_ST 0x00000007 //From previous SDK
|
||||
#define SPI_ST_S 0 //From previous SDK
|
||||
|
||||
#define SPI_EXT3(i) (REG_SPI_BASE(i) + 0xFC)
|
||||
#define SPI_INT_HOLD_ENA 0x00000003
|
||||
#define SPI_INT_HOLD_ENA_S 0
|
||||
#endif // SPI_REGISTER_H_INCLUDED
|
||||
@@ -60,6 +60,7 @@ STATIC void mp_reset(void) {
|
||||
MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL;
|
||||
pin_init0();
|
||||
readline_init0();
|
||||
dupterm_task_init();
|
||||
#if MICROPY_MODULE_FROZEN
|
||||
pyexec_frozen_module("_boot.py");
|
||||
pyexec_file("boot.py");
|
||||
@@ -85,7 +86,6 @@ void init_done(void) {
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
pyexec_event_repl_init();
|
||||
#endif
|
||||
dupterm_task_init();
|
||||
|
||||
#if !MICROPY_REPL_EVENT_DRIVEN
|
||||
soft_reset:
|
||||
|
||||
@@ -1,23 +1,40 @@
|
||||
import sys
|
||||
import struct
|
||||
import hashlib
|
||||
|
||||
SEGS_MAX_SIZE = 0x9000
|
||||
|
||||
assert len(sys.argv) == 4
|
||||
|
||||
md5 = hashlib.md5()
|
||||
|
||||
with open(sys.argv[3], 'wb') as fout:
|
||||
|
||||
with open(sys.argv[1], 'rb') as f:
|
||||
data_flash = f.read()
|
||||
fout.write(data_flash)
|
||||
# First 4 bytes include flash size, etc. which may be changed
|
||||
# by esptool.py, etc.
|
||||
md5.update(data_flash[4:])
|
||||
print('flash ', len(data_flash))
|
||||
|
||||
pad = b'\xff' * (SEGS_MAX_SIZE - len(data_flash))
|
||||
fout.write(pad)
|
||||
print('padding ', len(pad))
|
||||
|
||||
with open(sys.argv[2], 'rb') as f:
|
||||
data_rom = f.read()
|
||||
fout.write(data_rom)
|
||||
print('irom0text', len(data_rom))
|
||||
|
||||
pad = b'\xff' * (SEGS_MAX_SIZE - len(data_flash))
|
||||
assert len(pad) >= 4
|
||||
fout.write(pad[:-4])
|
||||
md5.update(pad[:-4])
|
||||
len_data = struct.pack("I", SEGS_MAX_SIZE + len(data_rom))
|
||||
fout.write(len_data)
|
||||
md5.update(len_data)
|
||||
print('padding ', len(pad))
|
||||
|
||||
fout.write(data_rom)
|
||||
md5.update(data_rom)
|
||||
print('irom0text', len(data_rom))
|
||||
|
||||
fout.write(md5.digest())
|
||||
|
||||
print('total ', SEGS_MAX_SIZE + len(data_rom))
|
||||
print('md5 ', md5.hexdigest())
|
||||
|
||||
@@ -633,6 +633,24 @@ STATIC mp_obj_t esp_flash_size(void) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);
|
||||
|
||||
STATIC mp_obj_t esp_check_fw(void) {
|
||||
MD5_CTX ctx;
|
||||
uint32_t *sz_p = (uint32_t*)0x40208ffc;
|
||||
printf("size: %d\n", *sz_p);
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (char*)0x40200004, *sz_p - 4);
|
||||
unsigned char digest[16];
|
||||
MD5Final(digest, &ctx);
|
||||
printf("md5: ");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("%02x", digest[i]);
|
||||
}
|
||||
printf("\n");
|
||||
return mp_obj_new_bool(memcmp(digest, (void*)(0x40200000 + *sz_p), sizeof(digest)) == 0);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_check_fw_obj, esp_check_fw);
|
||||
|
||||
|
||||
STATIC mp_obj_t esp_neopixel_write_(mp_obj_t pin, mp_obj_t buf, mp_obj_t is800k) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
@@ -642,6 +660,7 @@ STATIC mp_obj_t esp_neopixel_write_(mp_obj_t pin, mp_obj_t buf, mp_obj_t is800k)
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_neopixel_write_obj, esp_neopixel_write_);
|
||||
|
||||
#if MICROPY_ESP8266_APA102
|
||||
STATIC mp_obj_t esp_apa102_write_(mp_obj_t clockPin, mp_obj_t dataPin, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
@@ -651,6 +670,7 @@ STATIC mp_obj_t esp_apa102_write_(mp_obj_t clockPin, mp_obj_t dataPin, mp_obj_t
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_apa102_write_obj, esp_apa102_write_);
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t esp_freemem() {
|
||||
return MP_OBJ_NEW_SMALL_INT(system_get_free_heap_size());
|
||||
@@ -695,10 +715,13 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&esp_getaddrinfo_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write), (mp_obj_t)&esp_neopixel_write_obj },
|
||||
#if MICROPY_ESP8266_APA102
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_apa102_write), (mp_obj_t)&esp_apa102_write_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dht_readinto), (mp_obj_t)&dht_readinto_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_freemem), (mp_obj_t)&esp_freemem_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_meminfo), (mp_obj_t)&esp_meminfo_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_check_fw), (mp_obj_t)&esp_check_fw_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj }, // TODO delete/rename/move elsewhere
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_malloc), (mp_obj_t)&esp_malloc_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_free), (mp_obj_t)&esp_free_obj },
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
@@ -48,6 +49,8 @@
|
||||
//#define MACHINE_WAKE_SLEEP (0x02)
|
||||
#define MACHINE_WAKE_DEEPSLEEP (0x04)
|
||||
|
||||
extern const mp_obj_type_t esp_wdt_type;
|
||||
|
||||
STATIC mp_obj_t machine_freq(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// get
|
||||
@@ -82,6 +85,18 @@ STATIC mp_obj_t machine_unique_id(void) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
|
||||
|
||||
STATIC mp_obj_t machine_idle(void) {
|
||||
asm("waiti 0");
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
|
||||
|
||||
STATIC mp_obj_t machine_sleep(void) {
|
||||
printf("Warning: not yet implemented\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_sleep_obj, machine_sleep);
|
||||
|
||||
STATIC mp_obj_t machine_deepsleep(void) {
|
||||
// default to sleep forever
|
||||
uint32_t sleep_us = 0;
|
||||
@@ -222,6 +237,8 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&machine_sleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&machine_deepsleep_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) },
|
||||
@@ -231,20 +248,23 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&pyb_rtc_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&esp_timer_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&esp_wdt_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&pyb_spi_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&pyb_hspi_type) },
|
||||
|
||||
// wake abilities
|
||||
{ MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) },
|
||||
|
||||
// reset causes
|
||||
{ MP_ROM_QSTR(MP_QSTR_PWR_ON_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(REASON_DEFAULT_RST) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(REASON_DEEP_SLEEP_AWAKE) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(REASON_WDT_RST) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(REASON_SOFT_RESTART) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
||||
|
||||
85
esp8266/modmachinewdt.c
Normal file
85
esp8266/modmachinewdt.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "user_interface.h"
|
||||
#include "etshal.h"
|
||||
|
||||
const mp_obj_type_t esp_wdt_type;
|
||||
|
||||
typedef struct _machine_wdt_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} machine_wdt_obj_t;
|
||||
|
||||
STATIC machine_wdt_obj_t wdt_default = {{&esp_wdt_type}};
|
||||
|
||||
STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
|
||||
mp_int_t id = 0;
|
||||
if (n_args > 0) {
|
||||
id = mp_obj_get_int(args[0]);
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
return &wdt_default;
|
||||
default:
|
||||
mp_raise_ValueError("");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
system_soft_wdt_feed();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed);
|
||||
|
||||
STATIC mp_obj_t machine_wdt_deinit(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
ets_wdt_disable();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_deinit_obj, machine_wdt_deinit);
|
||||
|
||||
STATIC const mp_map_elem_t machine_wdt_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_feed), (mp_obj_t)&machine_wdt_feed_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&machine_wdt_deinit_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t esp_wdt_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_WDT,
|
||||
.make_new = machine_wdt_make_new,
|
||||
.locals_dict = (mp_obj_t)&machine_wdt_locals_dict,
|
||||
};
|
||||
@@ -130,17 +130,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_status_obj, esp_status);
|
||||
|
||||
STATIC mp_obj_t *esp_scan_list = NULL;
|
||||
|
||||
STATIC void esp_scan_cb(scaninfo *si, STATUS status) {
|
||||
STATIC void esp_scan_cb(void *result, STATUS status) {
|
||||
if (esp_scan_list == NULL) {
|
||||
// called unexpectedly
|
||||
return;
|
||||
}
|
||||
if (si->pbss && status == 0) {
|
||||
if (result && status == 0) {
|
||||
// we need to catch any memory errors
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
struct bss_info *bs;
|
||||
STAILQ_FOREACH(bs, si->pbss, next) {
|
||||
for (struct bss_info *bs = result; bs; bs = STAILQ_NEXT(bs, next)) {
|
||||
mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL);
|
||||
#if 1
|
||||
// struct bss_info::ssid_len is not documented in SDK API Guide,
|
||||
|
||||
@@ -10,6 +10,8 @@ extern const mp_obj_type_t pyb_rtc_type;
|
||||
extern const mp_obj_type_t pyb_uart_type;
|
||||
extern const mp_obj_type_t pyb_i2c_type;
|
||||
extern const mp_obj_type_t pyb_spi_type;
|
||||
extern const mp_obj_type_t pyb_hspi_type;
|
||||
extern const mp_obj_type_t machine_spi_type;
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_info_obj);
|
||||
|
||||
|
||||
224
esp8266/modpybhspi.c
Normal file
224
esp8266/modpybhspi.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 "ets_sys.h"
|
||||
#include "etshal.h"
|
||||
#include "ets_alt_task.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
|
||||
#include "hspi.h"
|
||||
|
||||
mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args,
|
||||
size_t n_kw, const mp_obj_t *args);
|
||||
|
||||
typedef struct _pyb_hspi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint32_t baudrate;
|
||||
uint8_t polarity;
|
||||
uint8_t phase;
|
||||
} pyb_hspi_obj_t;
|
||||
|
||||
|
||||
STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
|
||||
(void)self_in;
|
||||
|
||||
if (dest_len == 0) {
|
||||
// fast case when we only need to write data
|
||||
size_t chunk_size = 1024;
|
||||
size_t count = src_len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
spi_tx8fast(HSPI, src_buf[i]);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < src_len) {
|
||||
spi_tx8fast(HSPI, src_buf[i]);
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
// we need to read and write data
|
||||
|
||||
// Process data in chunks, let the pending tasks run in between
|
||||
size_t chunk_size = 1024; // TODO this should depend on baudrate
|
||||
size_t count = dest_len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
uint32_t data_out;
|
||||
if (src_len == 1) {
|
||||
data_out = src_buf[0];
|
||||
} else {
|
||||
data_out = src_buf[i];
|
||||
}
|
||||
dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < dest_len) {
|
||||
uint32_t data_out;
|
||||
if (src_len == 1) {
|
||||
data_out = src_buf[0];
|
||||
} else {
|
||||
data_out = src_buf[i];
|
||||
}
|
||||
dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings for HSPI
|
||||
|
||||
STATIC void pyb_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_printf(print, "HSPI(id=1, baudrate=%u, polarity=%u, phase=%u)",
|
||||
self->baudrate, self->polarity, self->phase);
|
||||
}
|
||||
|
||||
STATIC void pyb_hspi_init_helper(pyb_hspi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args),
|
||||
allowed_args, args);
|
||||
|
||||
if (args[ARG_baudrate].u_int != -1) {
|
||||
self->baudrate = args[ARG_baudrate].u_int;
|
||||
}
|
||||
if (args[ARG_polarity].u_int != -1) {
|
||||
self->polarity = args[ARG_polarity].u_int;
|
||||
}
|
||||
if (args[ARG_phase].u_int != -1) {
|
||||
self->phase = args[ARG_phase].u_int;
|
||||
}
|
||||
if (self->baudrate == 80000000L) {
|
||||
// Special case for full speed.
|
||||
spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV);
|
||||
spi_clock(HSPI, 0, 0);
|
||||
} else if (self->baudrate > 40000000L) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
|
||||
"impossible baudrate"));
|
||||
} else {
|
||||
uint32_t divider = 40000000L / self->baudrate;
|
||||
uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1);
|
||||
uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even
|
||||
if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
|
||||
"impossible baudrate"));
|
||||
}
|
||||
self->baudrate = 80000000L / (prediv * cntdiv);
|
||||
spi_init_gpio(HSPI, SPI_CLK_USE_DIV);
|
||||
spi_clock(HSPI, prediv, cntdiv);
|
||||
}
|
||||
// TODO: Make the byte order configurable too (discuss param names)
|
||||
spi_tx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
spi_rx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE | SPI_USR_MISO |
|
||||
SPI_USR_ADDR | SPI_USR_COMMAND | SPI_USR_DUMMY);
|
||||
// Clear Dual or Quad lines transmission mode
|
||||
CLEAR_PERI_REG_MASK(SPI_CTRL(HSPI), SPI_QIO_MODE | SPI_DIO_MODE |
|
||||
SPI_DOUT_MODE | SPI_QOUT_MODE);
|
||||
spi_mode(HSPI, self->phase, self->polarity);
|
||||
}
|
||||
|
||||
mp_obj_t pyb_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, true);
|
||||
mp_int_t id = -1;
|
||||
if (n_args > 0) {
|
||||
id = mp_obj_get_int(args[0]);
|
||||
}
|
||||
|
||||
if (id == -1) {
|
||||
// Multiplex to bitbanging SPI
|
||||
if (n_args > 0) {
|
||||
args++;
|
||||
}
|
||||
return pyb_spi_make_new(type, 0, n_kw, args);
|
||||
}
|
||||
|
||||
if (id != 1) {
|
||||
// FlashROM is on SPI0, so far we don't support its usage
|
||||
mp_raise_ValueError("");
|
||||
}
|
||||
|
||||
pyb_hspi_obj_t *self = m_new_obj(pyb_hspi_obj_t);
|
||||
self->base.type = &pyb_hspi_type;
|
||||
// set defaults
|
||||
self->baudrate = 80000000L;
|
||||
self->polarity = 0;
|
||||
self->phase = 0;
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_hspi_init_helper(self, n_args, args, &kw_args);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_hspi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
pyb_hspi_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_hspi_init_obj, 1, pyb_hspi_init);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_hspi_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_hspi_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_hspi_locals_dict, pyb_hspi_locals_dict_table);
|
||||
|
||||
STATIC const mp_machine_spi_p_t pyb_hspi_p = {
|
||||
.transfer = hspi_transfer,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_hspi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_HSPI,
|
||||
.print = pyb_hspi_print,
|
||||
.make_new = pyb_hspi_make_new,
|
||||
.protocol = &pyb_hspi_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_hspi_locals_dict,
|
||||
};
|
||||
@@ -244,7 +244,11 @@ STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, mp_uint_t n_args, c
|
||||
|
||||
// configure the GPIO as requested
|
||||
if (self->phys_port == 16) {
|
||||
// TODO: Set pull up/pull down
|
||||
// only pull-down seems to be supported by the hardware, and
|
||||
// we only expose pull-up behaviour in software
|
||||
if (pull != GPIO_PULL_NONE) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Pin(16) doesn't support pull"));
|
||||
}
|
||||
} else {
|
||||
PIN_FUNC_SELECT(self->periph, self->func);
|
||||
#if 0
|
||||
@@ -301,7 +305,7 @@ STATIC mp_obj_t pyb_pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
if (n_args == 0) {
|
||||
// get pin
|
||||
return MP_OBJ_NEW_SMALL_INT(GPIO_INPUT_GET(self->phys_port));
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get(self->phys_port));
|
||||
} else {
|
||||
// set pin
|
||||
pin_set(self->phys_port, mp_obj_is_true(args[0]));
|
||||
|
||||
@@ -212,7 +212,7 @@ STATIC mp_obj_t pyb_rtc_alarm(mp_obj_t self_in, mp_obj_t alarm_id, mp_obj_t time
|
||||
}
|
||||
|
||||
// set expiry time (in microseconds)
|
||||
pyb_rtc_alarm0_expiry = pyb_rtc_get_us_since_2000() + mp_obj_get_int(time_in) * 1000;
|
||||
pyb_rtc_alarm0_expiry = pyb_rtc_get_us_since_2000() + (uint64_t)mp_obj_get_int(time_in) * 1000;
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
|
||||
typedef struct _pyb_spi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
@@ -46,7 +47,8 @@ typedef struct _pyb_spi_obj_t {
|
||||
mp_hal_pin_obj_t miso;
|
||||
} pyb_spi_obj_t;
|
||||
|
||||
STATIC void mp_hal_spi_transfer(pyb_spi_obj_t *self, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
|
||||
STATIC void mp_hal_spi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) {
|
||||
pyb_spi_obj_t *self = (pyb_spi_obj_t*)self_in;
|
||||
// only MSB transfer is implemented
|
||||
uint32_t delay_half = 500000 / self->baudrate + 1;
|
||||
for (size_t i = 0; i < src_len || i < dest_len; ++i) {
|
||||
@@ -131,7 +133,7 @@ STATIC void pyb_spi_init_helper(pyb_spi_obj_t *self, size_t n_args, const mp_obj
|
||||
mp_hal_pin_input(self->miso);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
pyb_spi_obj_t *self = m_new_obj(pyb_spi_obj_t);
|
||||
self->base.type = &pyb_spi_type;
|
||||
@@ -154,69 +156,25 @@ STATIC mp_obj_t pyb_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_a
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_init_obj, 1, pyb_spi_init);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_read(size_t n_args, const mp_obj_t *args) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(args[1]));
|
||||
mp_hal_spi_transfer(self, 1, &write_byte, vstr.len, (uint8_t*)vstr.buf);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_spi_read_obj, 2, 3, pyb_spi_read);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_readinto(size_t n_args, const mp_obj_t *args) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
|
||||
uint8_t write_byte = 0;
|
||||
if (n_args == 3) {
|
||||
write_byte = mp_obj_get_int(args[2]);
|
||||
}
|
||||
mp_hal_spi_transfer(self, 1, &write_byte, bufinfo.len, (uint8_t*)bufinfo.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_spi_readinto_obj, 2, 3, pyb_spi_readinto);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_write(mp_obj_t self_in, mp_obj_t wr_buf_in) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_buffer_info_t src_buf;
|
||||
mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ);
|
||||
mp_hal_spi_transfer(self, src_buf.len, (const uint8_t*)src_buf.buf, 0, NULL);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_write_obj, pyb_spi_write);
|
||||
|
||||
STATIC mp_obj_t pyb_spi_write_readinto(mp_obj_t self_in, mp_obj_t wr_buf_in, mp_obj_t rd_buf_in) {
|
||||
pyb_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_buffer_info_t src_buf;
|
||||
mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ);
|
||||
mp_buffer_info_t dest_buf;
|
||||
mp_get_buffer_raise(rd_buf_in, &dest_buf, MP_BUFFER_WRITE);
|
||||
if (src_buf.len != dest_buf.len) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "buffers must be the same length"));
|
||||
}
|
||||
mp_hal_spi_transfer(self, src_buf.len, (const uint8_t*)src_buf.buf, dest_buf.len, (uint8_t*)dest_buf.buf);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_3(pyb_spi_write_readinto_obj, pyb_spi_write_readinto);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_spi_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&pyb_spi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&pyb_spi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_spi_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&pyb_spi_write_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table);
|
||||
|
||||
STATIC const mp_machine_spi_p_t pyb_spi_p = {
|
||||
.transfer = mp_hal_spi_transfer,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_spi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SPI,
|
||||
.name = MP_QSTR_SoftSPI,
|
||||
.print = pyb_spi_print,
|
||||
.make_new = pyb_spi_make_new,
|
||||
.protocol = &pyb_spi_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_spi_locals_dict,
|
||||
};
|
||||
|
||||
@@ -112,9 +112,11 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
|
||||
if (args[ARG_parity].u_obj != MP_OBJ_NULL) {
|
||||
if (args[ARG_parity].u_obj == mp_const_none) {
|
||||
UartDev.parity = UART_NONE_BITS;
|
||||
UartDev.exist_parity = UART_STICK_PARITY_DIS;
|
||||
self->parity = 0;
|
||||
} else {
|
||||
mp_int_t parity = mp_obj_get_int(args[ARG_parity].u_obj);
|
||||
UartDev.exist_parity = UART_STICK_PARITY_EN;
|
||||
if (parity & 1) {
|
||||
UartDev.parity = UART_ODD_BITS;
|
||||
self->parity = 1;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import gc
|
||||
gc.threshold((gc.mem_free() + gc.mem_alloc()) // 4)
|
||||
import uos
|
||||
from flashbdev import bdev
|
||||
|
||||
|
||||
46
esp8266/modules/ds18x20.py
Normal file
46
esp8266/modules/ds18x20.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# DS18x20 temperature sensor driver for MicroPython.
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
_CONVERT = const(0x44)
|
||||
_RD_SCRATCH = const(0xbe)
|
||||
_WR_SCRATCH = const(0x4e)
|
||||
|
||||
class DS18X20:
|
||||
def __init__(self, onewire):
|
||||
self.ow = onewire
|
||||
self.buf = bytearray(9)
|
||||
|
||||
def scan(self):
|
||||
return [rom for rom in self.ow.scan() if rom[0] == 0x10 or rom[0] == 0x28]
|
||||
|
||||
def convert_temp(self):
|
||||
self.ow.reset(True)
|
||||
self.ow.writebyte(self.ow.SKIP_ROM)
|
||||
self.ow.writebyte(_CONVERT)
|
||||
|
||||
def read_scratch(self, rom):
|
||||
self.ow.reset(True)
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(_RD_SCRATCH)
|
||||
self.ow.readinto(self.buf)
|
||||
if self.ow.crc8(self.buf):
|
||||
raise Exception('CRC error')
|
||||
return self.buf
|
||||
|
||||
def write_scratch(self, rom, buf):
|
||||
self.ow.reset(True)
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(_WR_SCRATCH)
|
||||
self.ow.write(buf)
|
||||
|
||||
def read_temp(self, rom):
|
||||
buf = self.read_scratch(rom)
|
||||
if rom[0] == 0x10:
|
||||
if buf[1]:
|
||||
t = buf[0] >> 1 | 0x80
|
||||
t = -((~t + 1) & 0xff)
|
||||
else:
|
||||
t = buf[0] >> 1
|
||||
return t - 0.25 + (buf[7] - buf[6]) / buf[7]
|
||||
else:
|
||||
return (buf[1] << 8 | buf[0]) / 16
|
||||
@@ -3,8 +3,8 @@ import esp
|
||||
class FlashBdev:
|
||||
|
||||
SEC_SIZE = 4096
|
||||
START_SEC = 0x89000 // SEC_SIZE
|
||||
NUM_BLK = 0x73
|
||||
START_SEC = 0x90000 // SEC_SIZE
|
||||
NUM_BLK = 0x6b
|
||||
|
||||
def __init__(self, blocks=NUM_BLK):
|
||||
self.blocks = blocks
|
||||
@@ -64,5 +64,5 @@ size = esp.flash_size()
|
||||
if size < 1024*1024:
|
||||
bdev = None
|
||||
else:
|
||||
# 16K at the flash end is reserved for SDK params storage
|
||||
bdev = FlashBdev((size - 16384) // FlashBdev.SEC_SIZE - FlashBdev.START_SEC)
|
||||
# 20K at the flash end is reserved for SDK params storage
|
||||
bdev = FlashBdev((size - 20480) // FlashBdev.SEC_SIZE - FlashBdev.START_SEC)
|
||||
|
||||
@@ -15,8 +15,11 @@ class OneWire:
|
||||
self.pin = pin
|
||||
self.pin.init(pin.OPEN_DRAIN)
|
||||
|
||||
def reset(self):
|
||||
return _ow.reset(self.pin)
|
||||
def reset(self, required=False):
|
||||
reset = _ow.reset(self.pin)
|
||||
if required and not reset:
|
||||
raise OneWireError
|
||||
return reset
|
||||
|
||||
def readbit(self):
|
||||
return _ow.readbit(self.pin)
|
||||
@@ -24,11 +27,9 @@ class OneWire:
|
||||
def readbyte(self):
|
||||
return _ow.readbyte(self.pin)
|
||||
|
||||
def read(self, count):
|
||||
buf = bytearray(count)
|
||||
for i in range(count):
|
||||
def readinto(self, buf):
|
||||
for i in range(len(buf)):
|
||||
buf[i] = _ow.readbyte(self.pin)
|
||||
return buf
|
||||
|
||||
def writebit(self, value):
|
||||
return _ow.writebit(self.pin, value)
|
||||
@@ -87,41 +88,3 @@ class OneWire:
|
||||
|
||||
def crc8(self, data):
|
||||
return _ow.crc8(data)
|
||||
|
||||
class DS18B20:
|
||||
CONVERT = const(0x44)
|
||||
RD_SCRATCH = const(0xbe)
|
||||
WR_SCRATCH = const(0x4e)
|
||||
|
||||
def __init__(self, onewire):
|
||||
self.ow = onewire
|
||||
|
||||
def scan(self):
|
||||
return [rom for rom in self.ow.scan() if rom[0] == 0x28]
|
||||
|
||||
def convert_temp(self):
|
||||
if not self.ow.reset():
|
||||
raise OneWireError
|
||||
self.ow.writebyte(SKIP_ROM)
|
||||
self.ow.writebyte(CONVERT)
|
||||
|
||||
def read_scratch(self, rom):
|
||||
if not self.ow.reset():
|
||||
raise OneWireError
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(RD_SCRATCH)
|
||||
buf = self.ow.read(9)
|
||||
if self.ow.crc8(buf):
|
||||
raise OneWireError
|
||||
return buf
|
||||
|
||||
def write_scratch(self, rom, buf):
|
||||
if not self.ow.reset():
|
||||
raise OneWireError
|
||||
self.ow.select_rom(rom)
|
||||
self.ow.writebyte(WR_SCRATCH)
|
||||
self.ow.write(buf)
|
||||
|
||||
def read_temp(self, rom):
|
||||
buf = self.read_scratch(rom)
|
||||
return (buf[1] << 8 | buf[0]) / 16
|
||||
@@ -95,6 +95,11 @@ STATIC mp_obj_t os_mkdir(mp_obj_t path_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
||||
|
||||
STATIC mp_obj_t os_rmdir(mp_obj_t path_in) {
|
||||
return vfs_proxy_call(MP_QSTR_rmdir, 1, &path_in);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
|
||||
|
||||
STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
return vfs_proxy_call(MP_QSTR_chdir, 1, &path_in);
|
||||
}
|
||||
@@ -118,6 +123,10 @@ STATIC mp_obj_t os_rename(mp_obj_t path_old, mp_obj_t path_new) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
||||
|
||||
STATIC mp_obj_t os_umount(void) {
|
||||
return vfs_proxy_call(MP_QSTR_umount, 0, NULL);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_umount_obj, os_umount);
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
@@ -155,11 +164,13 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&os_listdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&os_mkdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&os_rmdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&os_chdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&os_getcwd_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&os_remove_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&os_rename_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&os_stat_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&os_umount_obj) },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -134,8 +134,7 @@ STATIC mp_obj_t time_ticks_us(void) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
|
||||
|
||||
STATIC mp_obj_t time_ticks_cpu(void) {
|
||||
// TODO
|
||||
return MP_OBJ_NEW_SMALL_INT(0 & MP_SMALL_INT_POSITIVE_MASK);
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_USE_INTERNAL_ERRNO (1)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
|
||||
#define MICROPY_PY_BUILTINS_COMPLEX (0)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
|
||||
@@ -62,6 +63,7 @@
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_PY_MACHINE_PULSE (1)
|
||||
#define MICROPY_PY_MACHINE_I2C (1)
|
||||
#define MICROPY_PY_MACHINE_SPI (1)
|
||||
#define MICROPY_PY_WEBSOCKET (1)
|
||||
#define MICROPY_PY_WEBREPL (1)
|
||||
#define MICROPY_PY_WEBREPL_DELAY (20)
|
||||
@@ -72,7 +74,10 @@
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL)
|
||||
#define MICROPY_WARNINGS (1)
|
||||
#define MICROPY_PY_STR_BYTES_CMP_WARN (1)
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_STREAMS_POSIX_API (1)
|
||||
#define MICROPY_MODULE_FROZEN_STR (1)
|
||||
#define MICROPY_MODULE_FROZEN_MPY (1)
|
||||
#define MICROPY_MODULE_FROZEN_LEXER mp_lexer_new_from_str32
|
||||
@@ -85,6 +90,7 @@
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
#define MICROPY_FSUSERMOUNT (1)
|
||||
#define MICROPY_VFS_FAT (1)
|
||||
#define MICROPY_ESP8266_APA102 (1)
|
||||
|
||||
#define MICROPY_EVENT_POLL_HOOK {ets_event_poll();}
|
||||
#define MICROPY_VM_HOOK_COUNT (10)
|
||||
@@ -110,10 +116,10 @@
|
||||
|
||||
typedef int32_t mp_int_t; // must be pointer size
|
||||
typedef uint32_t 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;
|
||||
typedef uint32_t sys_prot_t; // for modlwip
|
||||
// ssize_t, off_t as required by POSIX-signatured functions in stream.h
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ def setup():
|
||||
with open("/boot.py", "w") as f:
|
||||
f.write("""\
|
||||
# This file is executed on every boot (including wake-boot from deepsleep)
|
||||
#import esp
|
||||
#esp.osdebug(None)
|
||||
import gc
|
||||
#import webrepl
|
||||
#webrepl.start()
|
||||
|
||||
@@ -17,6 +17,8 @@ def main():
|
||||
FREQ_MAP = {0: "40MHZ", 1: "26MHZ", 2: "20MHz", 0xf: "80MHz"}
|
||||
print("Byte @2: %02x" % ROM[2])
|
||||
print("Byte @3: %02x (Flash size: %s Flash freq: %s)" % (ROM[3], SZ_MAP.get(ROM[3] >> 4, "?"), FREQ_MAP.get(ROM[3] & 0xf)))
|
||||
print("Firmware checksum:")
|
||||
print(esp.check_fw())
|
||||
|
||||
print("\nNetworking:")
|
||||
print("STA ifconfig:", network.WLAN(network.STA_IF).ifconfig())
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _INCLUDED_UART_H_
|
||||
#define _INCLUDED_UART_H_
|
||||
|
||||
#include <eagle_soc.h>
|
||||
|
||||
#define UART0 (0)
|
||||
#define UART1 (1)
|
||||
|
||||
@@ -18,14 +20,14 @@ typedef enum {
|
||||
} UartStopBitsNum;
|
||||
|
||||
typedef enum {
|
||||
UART_NONE_BITS = 0,
|
||||
UART_ODD_BITS = 0,
|
||||
UART_EVEN_BITS = BIT4
|
||||
UART_NONE_BITS = 0,
|
||||
UART_ODD_BITS = BIT0,
|
||||
UART_EVEN_BITS = 0
|
||||
} UartParityMode;
|
||||
|
||||
typedef enum {
|
||||
UART_STICK_PARITY_DIS = 0,
|
||||
UART_STICK_PARITY_EN = BIT3 | BIT5
|
||||
UART_STICK_PARITY_EN = BIT1
|
||||
} UartExistParity;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -16,10 +16,10 @@ pyb.LED(3).off() # indicate that we finished waiting for the swit
|
||||
pyb.LED(4).on() # indicate that we are selecting the mode
|
||||
|
||||
if switch_value:
|
||||
pyb.usb_mode('CDC+MSC')
|
||||
pyb.usb_mode('VCP+MSC')
|
||||
pyb.main('cardreader.py') # if switch was pressed, run this
|
||||
else:
|
||||
pyb.usb_mode('CDC+HID')
|
||||
pyb.usb_mode('VCP+HID')
|
||||
pyb.main('datalogger.py') # if switch wasn't pressed, run this
|
||||
|
||||
pyb.LED(4).off() # indicate that we finished selecting the mode
|
||||
|
||||
8
examples/embedding/Makefile
Normal file
8
examples/embedding/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
MPTOP = ../..
|
||||
CFLAGS = -std=c99 -I. -I$(MPTOP) -DNO_QSTR
|
||||
LDFLAGS = -L.
|
||||
|
||||
hello-embed: hello-embed.o -lmicropython
|
||||
|
||||
-lmicropython:
|
||||
$(MAKE) -f $(MPTOP)/examples/embedding/Makefile.upylib MPTOP=$(MPTOP)
|
||||
200
examples/embedding/Makefile.upylib
Normal file
200
examples/embedding/Makefile.upylib
Normal file
@@ -0,0 +1,200 @@
|
||||
MPTOP = ../..
|
||||
-include mpconfigport.mk
|
||||
include $(MPTOP)/py/mkenv.mk
|
||||
|
||||
all: lib
|
||||
|
||||
# OS name, for simple autoconfig
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
# include py core make definitions
|
||||
include $(MPTOP)/py/py.mk
|
||||
|
||||
INC += -I.
|
||||
INC += -I..
|
||||
INC += -I$(MPTOP)
|
||||
INC += -I$(MPTOP)/unix
|
||||
#INC += -I../lib/timeutils
|
||||
INC += -I$(BUILD)
|
||||
|
||||
# compiler settings
|
||||
CWARN = -Wall -Werror
|
||||
CWARN += -Wpointer-arith -Wuninitialized
|
||||
CFLAGS = $(INC) $(CWARN) -ansi -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
|
||||
|
||||
# Debugging/Optimization
|
||||
ifdef DEBUG
|
||||
CFLAGS += -g
|
||||
COPT = -O0
|
||||
else
|
||||
COPT = -Os #-DNDEBUG
|
||||
# _FORTIFY_SOURCE is a feature in gcc/glibc which is intended to provide extra
|
||||
# security for detecting buffer overflows. Some distros (Ubuntu at the very least)
|
||||
# have it enabled by default.
|
||||
#
|
||||
# gcc already optimizes some printf calls to call puts and/or putchar. When
|
||||
# _FORTIFY_SOURCE is enabled and compiling with -O1 or greater, then some
|
||||
# printf calls will also be optimized to call __printf_chk (in glibc). Any
|
||||
# printfs which get redirected to __printf_chk are then no longer synchronized
|
||||
# with printfs that go through mp_printf.
|
||||
#
|
||||
# In MicroPython, we don't want to use the runtime library's printf but rather
|
||||
# go through mp_printf, so that stdout is properly tied into streams, etc.
|
||||
# This means that we either need to turn off _FORTIFY_SOURCE or provide our
|
||||
# own implementation of __printf_chk. We've chosen to turn off _FORTIFY_SOURCE.
|
||||
# It should also be noted that the use of printf in MicroPython is typically
|
||||
# quite limited anyways (primarily for debug and some error reporting, etc
|
||||
# in the unix version).
|
||||
#
|
||||
# Information about _FORTIFY_SOURCE seems to be rather scarce. The best I could
|
||||
# find was this: https://securityblog.redhat.com/2014/03/26/fortify-and-you/
|
||||
# Original patchset was introduced by
|
||||
# https://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html .
|
||||
#
|
||||
# Turning off _FORTIFY_SOURCE is only required when compiling with -O1 or greater
|
||||
CFLAGS += -U _FORTIFY_SOURCE
|
||||
endif
|
||||
|
||||
# On OSX, 'gcc' is a symlink to clang unless a real gcc is installed.
|
||||
# The unix port of micropython on OSX must be compiled with clang,
|
||||
# while cross-compile ports require gcc, so we test here for OSX and
|
||||
# if necessary override the value of 'CC' set in py/mkenv.mk
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CC = clang
|
||||
# Use clang syntax for map file
|
||||
LDFLAGS_ARCH = -Wl,-map,$@.map
|
||||
else
|
||||
# Use gcc syntax for map file
|
||||
LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref
|
||||
endif
|
||||
LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA)
|
||||
|
||||
ifeq ($(MICROPY_FORCE_32BIT),1)
|
||||
# Note: you may need to install i386 versions of dependency packages,
|
||||
# starting with linux-libc-dev:i386
|
||||
ifeq ($(MICROPY_PY_FFI),1)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
CFLAGS_MOD += -I/usr/include/i686-linux-gnu
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(MICROPY_USE_READLINE),1)
|
||||
INC += -I../lib/mp-readline
|
||||
CFLAGS_MOD += -DMICROPY_USE_READLINE=1
|
||||
LIB_SRC_C_EXTRA += mp-readline/readline.c
|
||||
endif
|
||||
ifeq ($(MICROPY_USE_READLINE),2)
|
||||
CFLAGS_MOD += -DMICROPY_USE_READLINE=2
|
||||
LDFLAGS_MOD += -lreadline
|
||||
# the following is needed for BSD
|
||||
#LDFLAGS_MOD += -ltermcap
|
||||
endif
|
||||
ifeq ($(MICROPY_PY_TIME),1)
|
||||
CFLAGS_MOD += -DMICROPY_PY_TIME=1
|
||||
SRC_MOD += modtime.c
|
||||
endif
|
||||
ifeq ($(MICROPY_PY_TERMIOS),1)
|
||||
CFLAGS_MOD += -DMICROPY_PY_TERMIOS=1
|
||||
SRC_MOD += modtermios.c
|
||||
endif
|
||||
ifeq ($(MICROPY_PY_SOCKET),1)
|
||||
CFLAGS_MOD += -DMICROPY_PY_SOCKET=1
|
||||
SRC_MOD += modsocket.c
|
||||
endif
|
||||
|
||||
ifeq ($(MICROPY_PY_FFI),1)
|
||||
|
||||
ifeq ($(MICROPY_STANDALONE),1)
|
||||
LIBFFI_CFLAGS_MOD := -I$(shell ls -1d ../lib/libffi/build_dir/out/lib/libffi-*/include)
|
||||
ifeq ($(MICROPY_FORCE_32BIT),1)
|
||||
LIBFFI_LDFLAGS_MOD = ../lib/libffi/build_dir/out/lib32/libffi.a
|
||||
else
|
||||
LIBFFI_LDFLAGS_MOD = ../lib/libffi/build_dir/out/lib/libffi.a
|
||||
endif
|
||||
else
|
||||
LIBFFI_CFLAGS_MOD := $(shell pkg-config --cflags libffi)
|
||||
LIBFFI_LDFLAGS_MOD := $(shell pkg-config --libs libffi)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
LIBFFI_LDFLAGS_MOD += -ldl
|
||||
endif
|
||||
|
||||
CFLAGS_MOD += $(LIBFFI_CFLAGS_MOD) -DMICROPY_PY_FFI=1
|
||||
LDFLAGS_MOD += $(LIBFFI_LDFLAGS_MOD)
|
||||
SRC_MOD += modffi.c
|
||||
endif
|
||||
|
||||
MAIN_C = main.c
|
||||
|
||||
# source files
|
||||
SRC_C = $(addprefix $(MPTOP)/unix/,\
|
||||
$(MAIN_C) \
|
||||
gccollect.c \
|
||||
unix_mphal.c \
|
||||
input.c \
|
||||
file.c \
|
||||
modmachine.c \
|
||||
modos.c \
|
||||
moduselect.c \
|
||||
alloc.c \
|
||||
coverage.c \
|
||||
fatfs_port.c \
|
||||
$(SRC_MOD) \
|
||||
)
|
||||
|
||||
LIB_SRC_C = $(addprefix lib/,\
|
||||
$(LIB_SRC_C_EXTRA) \
|
||||
utils/printf.c \
|
||||
timeutils/timeutils.c \
|
||||
)
|
||||
|
||||
ifeq ($(MICROPY_FATFS),1)
|
||||
LIB_SRC_C += $(addprefix lib/,\
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
)
|
||||
endif
|
||||
|
||||
OBJ = $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(STMHAL_SRC_C:.c=.o))
|
||||
|
||||
# List of sources for qstr extraction
|
||||
SRC_QSTR += $(SRC_C) $(LIB_SRC_C)
|
||||
# Append any auto-generated sources that are needed by sources listed in
|
||||
# SRC_QSTR
|
||||
SRC_QSTR_AUTO_DEPS +=
|
||||
|
||||
include $(MPTOP)/py/mkrules.mk
|
||||
|
||||
# Value of configure's --host= option (required for cross-compilation).
|
||||
# Deduce it from CROSS_COMPILE by default, but can be overriden.
|
||||
ifneq ($(CROSS_COMPILE),)
|
||||
CROSS_COMPILE_HOST = --host=$(patsubst %-,%,$(CROSS_COMPILE))
|
||||
else
|
||||
CROSS_COMPILE_HOST =
|
||||
endif
|
||||
|
||||
deplibs: libffi axtls
|
||||
|
||||
# install-exec-recursive & install-data-am targets are used to avoid building
|
||||
# docs and depending on makeinfo
|
||||
libffi:
|
||||
cd ../lib/libffi; git clean -d -x -f
|
||||
cd ../lib/libffi; ./autogen.sh
|
||||
mkdir -p ../lib/libffi/build_dir; cd ../lib/libffi/build_dir; \
|
||||
../configure $(CROSS_COMPILE_HOST) --prefix=$$PWD/out CC="$(CC)" CXX="$(CXX)" LD="$(LD)"; \
|
||||
make install-exec-recursive; make -C include install-data-am
|
||||
|
||||
axtls: ../lib/axtls/README
|
||||
cd ../lib/axtls; cp config/upyconfig config/.config
|
||||
cd ../lib/axtls; make oldconfig -B
|
||||
cd ../lib/axtls; make clean
|
||||
cd ../lib/axtls; make all CC="$(CC)" LD="$(LD)"
|
||||
|
||||
../lib/axtls/README:
|
||||
@echo "You cloned without --recursive, fetching submodules for you."
|
||||
(cd ..; git submodule update --init --recursive)
|
||||
66
examples/embedding/README
Normal file
66
examples/embedding/README
Normal file
@@ -0,0 +1,66 @@
|
||||
Example of embedding MicroPython in a standlone C application
|
||||
=============================================================
|
||||
|
||||
This directory contains a (very simple!) example of how to embed a MicroPython
|
||||
in an existing C application.
|
||||
|
||||
A C application is represented by the file hello-embed.c. It executes a simple
|
||||
Python statement which prints to the standard output.
|
||||
|
||||
|
||||
Building the example
|
||||
--------------------
|
||||
|
||||
Build the example is as simple as running:
|
||||
|
||||
make
|
||||
|
||||
It's worth to trace what's happening behind the scenes though:
|
||||
|
||||
1. As a first step, a MicroPython library is built. This is handled by a
|
||||
seperate makefile, Makefile.upylib. It is more or less complex, but the
|
||||
good news is that you won't need to change anything in it, just use it
|
||||
as is, the main Makefile shows how. What may need editing though is
|
||||
MicroPython configuration file. MicroPython is highly configurable, so
|
||||
you would need to build a library suiting your application well, while
|
||||
not bloating its size. Check the options in the file "mpconfigport.h".
|
||||
Included is a copy of "minimal" Unix port, which should be good start
|
||||
for minimal embedding. For list of all available options, see py/mpconfig.h.
|
||||
|
||||
2. Once the library is built, your application is compiled and linked with
|
||||
the MicroPython library produced in the previous step. The main Makefile
|
||||
is very simple and shows that changes you would need to do to your
|
||||
application's Makefile (or other build configuration) are also simple:
|
||||
|
||||
a) You would need to use C99 standard (you're using 15+ years old standard
|
||||
already, not a 25+ years old one, right?).
|
||||
|
||||
b) You need to provide path to MicroPython's top-level dir, for includes.
|
||||
|
||||
c) You need to include -DNO_QSTR compile-time flag.
|
||||
|
||||
d) Otherwise, just link with micropython library produced in step 1.
|
||||
|
||||
|
||||
Out of tree build
|
||||
-----------------
|
||||
|
||||
This example set up to work out of the box, being part of the MicroPython
|
||||
tree. Your application of course will be outside of its tree, but the
|
||||
only thing you need to do is to pass MPTOP variable pointing to
|
||||
MicroPython directory to both Makefiles (in this example, the main Makefile
|
||||
automatically pass it to Makefile.upylib; in your own Makefile, don't forget
|
||||
to use suitable value).
|
||||
|
||||
A practical way to embed MicroPython in your application is to include it
|
||||
as a git submodule. Suppose you included it as libs/micropython. Then in
|
||||
your main Makefile you would have something like:
|
||||
|
||||
~~~
|
||||
MPTOP = libs/micropython
|
||||
|
||||
my_app: $(MY_OBJS) -lmicropython
|
||||
|
||||
-lmicropython:
|
||||
$(MAKE) -f $(MPTOP)/examples/embedding/Makefile.upylib MPTOP=$(MPTOP)
|
||||
~~~
|
||||
74
examples/embedding/hello-embed.c
Normal file
74
examples/embedding/hello-embed.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/stackctrl.h"
|
||||
|
||||
static char heap[16384];
|
||||
|
||||
mp_obj_t execute_from_lexer(mp_lexer_t *lex) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT);
|
||||
mp_obj_t module_fun = mp_compile(&pt, lex->source_name, MP_EMIT_OPT_NONE, false);
|
||||
mp_call_function_0(module_fun);
|
||||
nlr_pop();
|
||||
return 0;
|
||||
} else {
|
||||
// uncaught exception
|
||||
return (mp_obj_t)nlr.ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Initialized stack limit
|
||||
mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4));
|
||||
// Initialize heap
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
// Initialize interpreter
|
||||
mp_init();
|
||||
|
||||
const char str[] = "print('Hello world of easy embedding!')";
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false);
|
||||
if (execute_from_lexer(lex)) {
|
||||
printf("Error\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
printf("FATAL: uncaught NLR %p\n", val);
|
||||
exit(1);
|
||||
}
|
||||
1
examples/embedding/mpconfigport.h
Symbolic link
1
examples/embedding/mpconfigport.h
Symbolic link
@@ -0,0 +1 @@
|
||||
mpconfigport_minimal.h
|
||||
135
examples/embedding/mpconfigport_minimal.h
Normal file
135
examples/embedding/mpconfigport_minimal.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_ALLOC_PATH_MAX (PATH_MAX)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_FINALISER (0)
|
||||
#define MICROPY_STACK_CHECK (0)
|
||||
#define MICROPY_COMP_CONST (0)
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (1)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_WARNINGS (0)
|
||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
|
||||
#define MICROPY_STREAMS_NON_BLOCK (0)
|
||||
#define MICROPY_OPT_COMPUTED_GOTO (0)
|
||||
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (0)
|
||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
|
||||
#define MICROPY_CPYTHON_COMPAT (0)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
|
||||
#define MICROPY_PY_BUILTINS_COMPILE (0)
|
||||
#define MICROPY_PY_BUILTINS_ENUMERATE (0)
|
||||
#define MICROPY_PY_BUILTINS_FILTER (0)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (0)
|
||||
#define MICROPY_PY_BUILTINS_REVERSED (0)
|
||||
#define MICROPY_PY_BUILTINS_SET (0)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (0)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (0)
|
||||
#define MICROPY_PY_BUILTINS_MIN_MAX (0)
|
||||
#define MICROPY_PY___FILE__ (0)
|
||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
|
||||
#define MICROPY_PY_GC (0)
|
||||
#define MICROPY_PY_GC_COLLECT_RETVAL (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_IO_FILEIO (0)
|
||||
#define MICROPY_PY_STRUCT (0)
|
||||
#define MICROPY_PY_SYS (1)
|
||||
#define MICROPY_PY_SYS_EXIT (0)
|
||||
#define MICROPY_PY_SYS_PLATFORM "linux"
|
||||
#define MICROPY_PY_SYS_MAXSIZE (0)
|
||||
#define MICROPY_PY_SYS_STDFILES (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_UCTYPES (0)
|
||||
#define MICROPY_PY_UZLIB (0)
|
||||
#define MICROPY_PY_UJSON (0)
|
||||
#define MICROPY_PY_URE (0)
|
||||
#define MICROPY_PY_UHEAPQ (0)
|
||||
#define MICROPY_PY_UHASHLIB (0)
|
||||
#define MICROPY_PY_UBINASCII (0)
|
||||
|
||||
extern const struct _mp_obj_module_t mp_module_os;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&mp_module_os }, \
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
mp_obj_t keyboard_interrupt_obj;
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Do not change anything beyond this line
|
||||
//////////////////////////////////////////
|
||||
|
||||
// Define to 1 to use undertested inefficient GC helper implementation
|
||||
// (if more efficient arch-specific one is not available).
|
||||
#ifndef MICROPY_GCREGS_SETJMP
|
||||
#ifdef __mips__
|
||||
#define MICROPY_GCREGS_SETJMP (1)
|
||||
#else
|
||||
#define MICROPY_GCREGS_SETJMP (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#ifdef __LP64__
|
||||
typedef long mp_int_t; // must be pointer size
|
||||
typedef unsigned long mp_uint_t; // must be pointer size
|
||||
#else
|
||||
// These are definitions for machines where sizeof(int) == sizeof(void*),
|
||||
// regardless for actual size.
|
||||
typedef int mp_int_t; // must be pointer size
|
||||
typedef unsigned int mp_uint_t; // must be pointer size
|
||||
#endif
|
||||
|
||||
#define BYTES_PER_WORD sizeof(mp_int_t)
|
||||
|
||||
// Cannot include <sys/types.h>, as it may lead to symbol name clashes
|
||||
#if _FILE_OFFSET_BITS == 64 && !defined(__LP64__)
|
||||
typedef long long mp_off_t;
|
||||
#else
|
||||
typedef long mp_off_t;
|
||||
#endif
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#ifdef __FreeBSD__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
@@ -24,5 +24,7 @@ def main(use_stream=False):
|
||||
s.send(b"GET / HTTP/1.0\n\n")
|
||||
print(s.recv(4096))
|
||||
|
||||
s.close()
|
||||
|
||||
|
||||
main()
|
||||
|
||||
@@ -32,5 +32,7 @@ def main(use_stream=True):
|
||||
s.send(b"GET / HTTP/1.0\n\n")
|
||||
print(s.recv(4096))
|
||||
|
||||
s.close()
|
||||
|
||||
|
||||
main()
|
||||
|
||||
@@ -10,7 +10,7 @@ HTTP/1.0 200 OK
|
||||
Hello #%d from MicroPython!
|
||||
"""
|
||||
|
||||
def main(use_stream=False):
|
||||
def main(micropython_optimize=False):
|
||||
s = socket.socket()
|
||||
|
||||
# Binding to all interfaces - server will be accessible to other hosts!
|
||||
@@ -26,20 +26,37 @@ def main(use_stream=False):
|
||||
counter = 0
|
||||
while True:
|
||||
res = s.accept()
|
||||
client_s = res[0]
|
||||
client_sock = res[0]
|
||||
client_addr = res[1]
|
||||
print("Client address:", client_addr)
|
||||
print("Client socket:", client_s)
|
||||
print("Request:")
|
||||
if use_stream:
|
||||
# MicroPython socket objects support stream (aka file) interface
|
||||
# directly.
|
||||
print(client_s.read(4096))
|
||||
client_s.write(CONTENT % counter)
|
||||
print("Client socket:", client_sock)
|
||||
|
||||
if not micropython_optimize:
|
||||
# To read line-oriented protocol (like HTTP) from a socket (and
|
||||
# avoid short read problem), it must be wrapped in a stream (aka
|
||||
# file-like) object. That's how you do it in CPython:
|
||||
client_stream = client_sock.makefile("rwb")
|
||||
else:
|
||||
print(client_s.recv(4096))
|
||||
client_s.send(CONTENT % counter)
|
||||
client_s.close()
|
||||
# .. but MicroPython socket objects support stream interface
|
||||
# directly, so calling .makefile() method is not required. If
|
||||
# you develop application which will run only on MicroPython,
|
||||
# especially on a resource-constrained embedded device, you
|
||||
# may take this shortcut to save resources.
|
||||
client_stream = client_sock
|
||||
|
||||
print("Request:")
|
||||
req = client_stream.readline()
|
||||
print(req)
|
||||
while True:
|
||||
h = client_stream.readline()
|
||||
if h == b"" or h == b"\r\n":
|
||||
break
|
||||
print(h)
|
||||
client_stream.write(CONTENT % counter)
|
||||
|
||||
client_stream.close()
|
||||
if not micropython_optimize:
|
||||
client_sock.close()
|
||||
counter += 1
|
||||
print()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user