mirror of
https://github.com/micropython/micropython.git
synced 2025-12-31 17:20:13 +01:00
Compare commits
241 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7b7d5f6ee | ||
|
|
709955b601 | ||
|
|
1db3577bcb | ||
|
|
0bfc57022d | ||
|
|
1511dd4f84 | ||
|
|
1c132c8587 | ||
|
|
40c6d57804 | ||
|
|
a09757f104 | ||
|
|
304a96d7d6 | ||
|
|
4e7dc97bdc | ||
|
|
103d12a877 | ||
|
|
b47931978f | ||
|
|
1db4253886 | ||
|
|
800d5cd16f | ||
|
|
c7df9c6c47 | ||
|
|
f601390ef8 | ||
|
|
7bab32ef89 | ||
|
|
c50772d19f | ||
|
|
c2a4e4effc | ||
|
|
6738c1dded | ||
|
|
d5e629ad0e | ||
|
|
aa9dbb1b03 | ||
|
|
5df81de7af | ||
|
|
a7c02c4538 | ||
|
|
8fbabab1a8 | ||
|
|
4a60cac916 | ||
|
|
717a958256 | ||
|
|
4ed7b7f751 | ||
|
|
a37d13c95d | ||
|
|
c3ae03ff18 | ||
|
|
351424e719 | ||
|
|
d792d9e49e | ||
|
|
d3b32caea4 | ||
|
|
0589c19d52 | ||
|
|
76abb2e623 | ||
|
|
2bdefea9d6 | ||
|
|
4865a22f78 | ||
|
|
ff987ccf11 | ||
|
|
bda7041294 | ||
|
|
d39d96b700 | ||
|
|
2d56df67cd | ||
|
|
57ebe1b27d | ||
|
|
28076f3d4b | ||
|
|
9a42eb541e | ||
|
|
cd87d20f46 | ||
|
|
c097ea5dd2 | ||
|
|
c98c128fe8 | ||
|
|
367d4d1098 | ||
|
|
3d91b1f67f | ||
|
|
82d08dccc6 | ||
|
|
8872abcbc4 | ||
|
|
37c6555b44 | ||
|
|
7667727021 | ||
|
|
e04aa96b4d | ||
|
|
5ab5ac5448 | ||
|
|
3d3ef36e97 | ||
|
|
1829d86ef5 | ||
|
|
9e00ac89d5 | ||
|
|
04ee5983fe | ||
|
|
47b9809d23 | ||
|
|
0116218fa8 | ||
|
|
c4dc1b5c23 | ||
|
|
7e7039b53c | ||
|
|
2378be4e93 | ||
|
|
8c8d7f3c60 | ||
|
|
e4c899a08c | ||
|
|
f54bdecff2 | ||
|
|
71d482df47 | ||
|
|
a9afcb159a | ||
|
|
a62c106974 | ||
|
|
6f218d7472 | ||
|
|
d8713d78f5 | ||
|
|
e282884e54 | ||
|
|
dbb4aef5e3 | ||
|
|
bf4576dc91 | ||
|
|
c3e37a0cde | ||
|
|
f27aa27a0c | ||
|
|
a1a2c411b2 | ||
|
|
b7a4f15b34 | ||
|
|
ad9daadf8a | ||
|
|
95f53461c2 | ||
|
|
d11317bcab | ||
|
|
94792dd88f | ||
|
|
5225e29ce7 | ||
|
|
f81684141e | ||
|
|
6fefd5d330 | ||
|
|
6bbbb1ab41 | ||
|
|
f1ed8c8a2e | ||
|
|
0458833072 | ||
|
|
abea1c38a9 | ||
|
|
9fbc265eb8 | ||
|
|
d34c4784a5 | ||
|
|
fdcb3b7ebb | ||
|
|
9472907ae1 | ||
|
|
ae2c81ff38 | ||
|
|
0f553fe10b | ||
|
|
271d18eb08 | ||
|
|
7c8b4c1a8b | ||
|
|
8b85d14b92 | ||
|
|
cf5b6f6974 | ||
|
|
8c1d23a0e2 | ||
|
|
ede0f3ab3d | ||
|
|
fd787c5e4e | ||
|
|
40d43ea88d | ||
|
|
5e9810396f | ||
|
|
f66ee4dfd7 | ||
|
|
8f6aad2f48 | ||
|
|
eaefc8b9d6 | ||
|
|
1f9e2188a6 | ||
|
|
956d765786 | ||
|
|
c52f1258a8 | ||
|
|
dea853d3a3 | ||
|
|
4735c45c51 | ||
|
|
fa90ab1407 | ||
|
|
d8837cea6f | ||
|
|
c3184aea63 | ||
|
|
5aa311d330 | ||
|
|
23a2b11abf | ||
|
|
43d56f9ba9 | ||
|
|
e521f0eb68 | ||
|
|
c8b60f013b | ||
|
|
2bb5f41611 | ||
|
|
f35b5d28db | ||
|
|
df5d9c77f4 | ||
|
|
d8475092d1 | ||
|
|
5008972fef | ||
|
|
d8cbbcaa9d | ||
|
|
404b68da88 | ||
|
|
b42a5050fb | ||
|
|
3e592531eb | ||
|
|
90e6d0c2ac | ||
|
|
e4b4e5aa31 | ||
|
|
0435e76250 | ||
|
|
03ec6e4d01 | ||
|
|
9253e7bdf7 | ||
|
|
6be0bbb886 | ||
|
|
5a11086d64 | ||
|
|
d15fe5a6b3 | ||
|
|
8892f71dd0 | ||
|
|
73f1a49137 | ||
|
|
c92c7a69fd | ||
|
|
7d6595fd18 | ||
|
|
50ea86fe8b | ||
|
|
2e5704d101 | ||
|
|
8bdbc20e74 | ||
|
|
23008db6e1 | ||
|
|
e3cd154317 | ||
|
|
259eaab9a9 | ||
|
|
2764a8ee8d | ||
|
|
f53a8e712f | ||
|
|
1c9a499135 | ||
|
|
c1a77a0c9f | ||
|
|
2cd247e819 | ||
|
|
dcbf62b43d | ||
|
|
7d5e34287c | ||
|
|
4c45921349 | ||
|
|
feff00e1a5 | ||
|
|
a102e01ce1 | ||
|
|
90aa7595b4 | ||
|
|
2941d5c714 | ||
|
|
a86d40ccd4 | ||
|
|
044c473de2 | ||
|
|
e72cda99fd | ||
|
|
5ae5ec986e | ||
|
|
7f9d1d6ab9 | ||
|
|
56beb01724 | ||
|
|
9a18e21066 | ||
|
|
4c37489f4c | ||
|
|
f7a26472af | ||
|
|
b1f68685ec | ||
|
|
99f7184073 | ||
|
|
c69b4310c8 | ||
|
|
b21786947f | ||
|
|
8b7faa31e1 | ||
|
|
6eb7530083 | ||
|
|
55fe92bb8f | ||
|
|
7a6dbaa89b | ||
|
|
b1bbe966c4 | ||
|
|
d07ccc5a39 | ||
|
|
d278e49475 | ||
|
|
6e25d955f4 | ||
|
|
d35ac956d1 | ||
|
|
91bc32dc16 | ||
|
|
4dea922610 | ||
|
|
df1637c580 | ||
|
|
e50cff69bb | ||
|
|
36cc84a2a9 | ||
|
|
e97dddcdca | ||
|
|
9988618e0e | ||
|
|
18bd51707c | ||
|
|
c7acfc90b9 | ||
|
|
c9aa1883ed | ||
|
|
78772ada0d | ||
|
|
282ca09f8e | ||
|
|
e2d44e30c7 | ||
|
|
96b60ed956 | ||
|
|
2192824ad8 | ||
|
|
3a84c8b58d | ||
|
|
e5c4362a98 | ||
|
|
97abe22963 | ||
|
|
9dd3640464 | ||
|
|
7e758b1cf8 | ||
|
|
b9d850227d | ||
|
|
56606f3475 | ||
|
|
0528c5a22a | ||
|
|
0f6424efda | ||
|
|
40fc01f406 | ||
|
|
2801e6fad8 | ||
|
|
7f59b4b2ca | ||
|
|
acf6aec71c | ||
|
|
620058cc57 | ||
|
|
ac2f7a7f6a | ||
|
|
82f37bf0d1 | ||
|
|
fa5950eb00 | ||
|
|
99957384ea | ||
|
|
4cd9ced8dc | ||
|
|
2cc5473021 | ||
|
|
c0dcf6e878 | ||
|
|
43ea73faa6 | ||
|
|
12ab9eda8d | ||
|
|
3f327cc4c6 | ||
|
|
567184e21e | ||
|
|
12a5e17afb | ||
|
|
dbc0191d5f | ||
|
|
7f1c98177b | ||
|
|
f0a8f21190 | ||
|
|
e6c6fe3275 | ||
|
|
390e92688c | ||
|
|
332a909d44 | ||
|
|
2039757b85 | ||
|
|
f88eec0de2 | ||
|
|
2686f9b3e8 | ||
|
|
d460a30711 | ||
|
|
3f42f32648 | ||
|
|
344057ac50 | ||
|
|
9d2c0c231c | ||
|
|
1bc534247c | ||
|
|
fdaac1dbf8 | ||
|
|
e178ef2520 | ||
|
|
47098efbda | ||
|
|
7b19e99edd |
31
.gitattributes
vendored
Normal file
31
.gitattributes
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Per default everything gets normalized and gets LF line endings on checkout.
|
||||
* text eol=lf
|
||||
|
||||
# These will always have CRLF line endings on checkout.
|
||||
*.vcxproj text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.bat text eol=crlf
|
||||
|
||||
# These are binary so should never be modified by git.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.dxf binary
|
||||
|
||||
# These should also not be modified by git.
|
||||
tests/basics/string_cr_conversion.py -text
|
||||
tests/basics/string_crlf_conversion.py -text
|
||||
stmhal/startup_stm32f40xx.s -text
|
||||
stmhal/pybcdc.inf_template -text
|
||||
stmhal/usbd_* -text
|
||||
stmhal/boards/*/stm32f4xx_hal_conf.h -text
|
||||
stmhal/cmsis/** -text
|
||||
stmhal/hal/** -text
|
||||
stmhal/usbdev/** -text
|
||||
stmhal/usbhost/** -text
|
||||
cc3200/hal/aes.c -text
|
||||
cc3200/hal/aes.h -text
|
||||
cc3200/hal/des.c -text
|
||||
cc3200/hal/i2s.c -text
|
||||
cc3200/hal/i2s.h -text
|
||||
cc3200/version.h -text
|
||||
lib/fatfs/** -text
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -33,5 +33,7 @@ tests/*.out
|
||||
######################
|
||||
__pycache__/
|
||||
|
||||
# Customized Makefile overrides
|
||||
# Customized Makefile/project overrides
|
||||
######################
|
||||
GNUmakefile
|
||||
user.props
|
||||
|
||||
@@ -339,6 +339,7 @@ today. The names appear in order of pledging.
|
||||
668 pmst - Italy
|
||||
671 Sergio Conde Gómez (skgsergio)
|
||||
672 Micromint, www.micromint.com
|
||||
673 Xie Yanbo, China
|
||||
675 Thank you
|
||||
677 Kacem Ben Dhiab
|
||||
679 CornishSteve
|
||||
@@ -375,6 +376,7 @@ today. The names appear in order of pledging.
|
||||
759 Padraic D. Hallinan
|
||||
760 Rob Fairbairn
|
||||
763 Zac Luzader
|
||||
768 Sam Shams
|
||||
773 terje nagel, dk
|
||||
775 Luc LEGER
|
||||
782 Luis M. Morales S.
|
||||
@@ -417,6 +419,7 @@ today. The names appear in order of pledging.
|
||||
868 Stephan Schulte, Germany
|
||||
869 Kenneth Henderick
|
||||
872 DaveP (www.davepeake.com)
|
||||
873 Markus Schuss, Austria
|
||||
876 Kyle Gordon, http://lodge.glasgownet.com
|
||||
877 Joseph Gerard Campbell
|
||||
881 Thanks for the board. Good luck to you. --Jason Doege
|
||||
@@ -477,6 +480,7 @@ today. The names appear in order of pledging.
|
||||
1007 Charles V Bock - Charles at CharlesBock dot com
|
||||
1010 Remember June 4th, 1989
|
||||
1012 Stuart Marsden
|
||||
1013 Herbert Graef, Stuttgart
|
||||
1014 Arthur P, USA
|
||||
1015 John Hall & Jeremy Armijo
|
||||
1017 Luciano Ramalho, Python.pro.br
|
||||
@@ -690,6 +694,7 @@ today. The names appear in order of pledging.
|
||||
1499 Ronald Eddy
|
||||
1500 SynShop Las Vegas
|
||||
1503 This is really cool. - Jack Conway
|
||||
1505 Victor Suarez, Argentina
|
||||
1507 Renesas Electronics America
|
||||
1509 Team
|
||||
1513 A. Lamborn KD0ZFY
|
||||
@@ -889,6 +894,7 @@ today. The names appear in order of pledging.
|
||||
1922 Nicci Tofts
|
||||
1925 Joshua Coxwell
|
||||
1926 Franklin Hamilton
|
||||
1928 Peter Korcz
|
||||
1929 Leroy Douglas
|
||||
1930 A ナルと fan from Nigeria who likes smileys, here's one for good measure :)
|
||||
1931 Kimmo Lahtinen, Finland
|
||||
|
||||
8
CONTRIBUTING.md
Normal file
8
CONTRIBUTING.md
Normal file
@@ -0,0 +1,8 @@
|
||||
When reporting an issue and especially submitting a pull request, please
|
||||
make sure that you are acquainted with Contributor Guidelines:
|
||||
|
||||
https://github.com/micropython/micropython/wiki/ContributorGuidelines
|
||||
|
||||
and Code Conventions:
|
||||
|
||||
https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md
|
||||
@@ -44,6 +44,8 @@ Additional components:
|
||||
mostly to control code size.
|
||||
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
- pic16bit/ -- a version of Micro Python for 16-bit PIC microcontrollers.
|
||||
- cc3200/ -- a version of Micro Python that runs on the CC3200 from TI.
|
||||
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
|
||||
- tests/ -- test framework and test scripts.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/pfenv.h"
|
||||
|
||||
void do_str(const char *src) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
@@ -23,7 +22,7 @@ void do_str(const char *src) {
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception
|
||||
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define MICROPY_PY___FILE__ (0)
|
||||
#define MICROPY_PY_GC (0)
|
||||
#define MICROPY_PY_ARRAY (0)
|
||||
#define MICROPY_PY_ATTRTUPLE (0)
|
||||
#define MICROPY_PY_COLLECTIONS (0)
|
||||
#define MICROPY_PY_MATH (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 )
|
||||
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 72 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16384 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 8 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
|
||||
@@ -28,12 +28,12 @@ make BTARGET=bootloader BTYPE=release
|
||||
- Make sure that you have built both the *bootloader* and the *application* in **release** mode.
|
||||
- Make sure the SOP2 jumper is in position.
|
||||
- Open CCS_Uniflash and connect to the board (by default on port 22).
|
||||
- Format the serial flash (select 1MB size in case of the CC3200-LAUNCHXL, leave the rest unchecked).
|
||||
- Format the serial flash (select 1MB size in case of the CC3200-LAUNCHXL, 2MB in case of the WiPy, leave the rest unchecked).
|
||||
- Mark the following files for erasing: `/cert/ca.pem`, `/cert/client.pm`, `/cert/private.key` and `/tmp/pac.bin`.
|
||||
- Add a new file with the name of /sys/mcuimg.bin, and select the URL to point to cc3200\bootmgr\build\<BOARD_NAME>\bootloader.bin.
|
||||
- Add another file with the name of /sys/factimg.bin, and select the URL to point to cc3200\build\<BOARD_NAME>\MCUIMG.BIN.
|
||||
- Add another file with the name of /sys/factimg.bin, and select the URL to point to cc3200\build\<BOARD_NAME>\mcuimg.bin.
|
||||
- Click "Program" to apply all changes.
|
||||
- Flash the latest service pack (servicepack_1.0.0.1.2.bin) using the "Service Pack Update" button.
|
||||
- Flash the latest service pack (servicepack_1.0.0.10.0.bin) using the "Service Pack Update" button.
|
||||
- Close CCS_Uniflash, remove the SOP2 jumper and reset the board.
|
||||
|
||||
## Playing with MicroPython and the CC3200:
|
||||
@@ -43,15 +43,14 @@ Once the software is running, you have two options to access the MicroPython REP
|
||||
- Through the UART.
|
||||
**Connect to PORT 22, baud rate = 115200, parity = none, stop bits = 1**
|
||||
- Through telnet.
|
||||
* Connect to the network created by the board (as boots up in AP mode), **ssid = "micropy-wlan", key = "micropython"**
|
||||
* Connect to the network created by the board (as boots up in AP mode), **ssid = "wipy-wlan", key = "www.wipy.io"**.
|
||||
* You can also reinitialize the WLAN in station mode and connect to another AP, or in AP mode but with a
|
||||
different ssid and/or key.
|
||||
* Use your favourite telnet client with the following settings: **host = 192.168.1.1, port = 23.**
|
||||
* Log in with **user = "micro" and password = "python"**
|
||||
|
||||
The board has a small file system of 64K located in the serial flash connected to the CC3200. SD cards are also supported, but
|
||||
since the CC3200 LaunchXL doesn't come with an SD card socket installed, you will need to add one yourself. Any SD card breakout
|
||||
board will do, as long as you connect it as described here: <http://processors.wiki.ti.com/index.php/CC32xx_SDHost_FatFS>
|
||||
The board has a small file system of 192K (WiPy) or 64K (Launchpad) located in the serial flash connected to the CC3200.
|
||||
SD cards are also supported, you can connect any SD card and configure the pinout using the SD class API.
|
||||
|
||||
## Uploading scripts:
|
||||
|
||||
@@ -64,14 +63,14 @@ not 100% sure of it.
|
||||
## Upgrading the firmware Over The Air:
|
||||
|
||||
OTA software updates can be performed through the FTP server. After building a new MCUIMG.BIN in release mode, upload it to:
|
||||
`/SFLASH/SYS/MCUIMG.BIN` it will take around 8s (The TI simplelink file system is quite slow because every file is mirrored for
|
||||
safety). You won't see the file being stored inside `/SFLASH/SYS/` because it's actually saved bypassing FatFS, but rest assured that
|
||||
`/flash/sys/mcuimg.bin` it will take around 6s (The TI simplelink file system is quite slow because every file is mirrored for
|
||||
safety). You won't see the file being stored inside `/flash/sys/` because it's actually saved bypassing FatFS, but rest assured that
|
||||
the file was successfully transferred, and it has been signed with a MD5 checksum to verify its integrity.
|
||||
Now, reset the MCU by pressing the switch on the board, or by typing:
|
||||
|
||||
```python
|
||||
import pyb
|
||||
pyb.hard_reset()
|
||||
pyb.reset()
|
||||
```
|
||||
|
||||
### Note regarding FileZilla:
|
||||
|
||||
@@ -20,6 +20,8 @@ APP_INC += -I$(BUILD)
|
||||
APP_INC += -I$(BUILD)/genhdr
|
||||
APP_INC += -I../lib/fatfs
|
||||
APP_INC += -I../lib/mp-readline
|
||||
APP_INC += -I../lib/netutils
|
||||
APP_INC += -I../lib/timeutils
|
||||
APP_INC += -I../stmhal
|
||||
|
||||
APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
|
||||
@@ -80,7 +82,6 @@ APP_MISC_SRC_C = $(addprefix misc/,\
|
||||
mperror.c \
|
||||
mpexception.c \
|
||||
mpsystick.c \
|
||||
pin_defs_cc3200.c \
|
||||
)
|
||||
|
||||
APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
@@ -140,7 +141,11 @@ APP_MAIN_SRC_C = \
|
||||
|
||||
APP_LIB_SRC_C = $(addprefix lib/,\
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
libc/string0.c \
|
||||
mp-readline/readline.c \
|
||||
netutils/netutils.c \
|
||||
timeutils/timeutils.c \
|
||||
)
|
||||
|
||||
APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
@@ -154,7 +159,6 @@ APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
printf.c \
|
||||
pyexec.c \
|
||||
pybstdio.c \
|
||||
string0.c \
|
||||
)
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(APP_FATFS_SRC_C:.c=.o) $(APP_RTOS_SRC_C:.c=.o) $(APP_FTP_SRC_C:.c=.o) $(APP_HAL_SRC_C:.c=.o) $(APP_MISC_SRC_C:.c=.o))
|
||||
@@ -206,7 +210,7 @@ endif
|
||||
SHELL = bash
|
||||
APP_SIGN = appsign.sh
|
||||
|
||||
all: $(BUILD)/MCUIMG.BIN
|
||||
all: $(BUILD)/mcuimg.bin
|
||||
|
||||
$(BUILD)/application.axf: $(OBJ) $(LINKER_SCRIPT)
|
||||
$(ECHO) "LINK $@"
|
||||
@@ -217,7 +221,7 @@ $(BUILD)/application.bin: $(BUILD)/application.axf
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(OBJCOPY) -O binary $< $@
|
||||
|
||||
$(BUILD)/MCUIMG.BIN: $(BUILD)/application.bin
|
||||
$(BUILD)/mcuimg.bin: $(BUILD)/application.bin
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(SHELL) $(APP_SIGN) $(BOARD) $(BTYPE)
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ BUILD=build/${BOARD}/${BTYPE}
|
||||
echo -n `md5sum --binary $BUILD/application.bin | awk '{ print $1 }'` > __md5hash.bin
|
||||
|
||||
# Concatenate it with the application binary
|
||||
cat $BUILD/application.bin __md5hash.bin > $BUILD/MCUIMG.BIN
|
||||
cat $BUILD/application.bin __md5hash.bin > $BUILD/mcuimg.bin
|
||||
RET=$?
|
||||
|
||||
# Remove the tmp files
|
||||
rm -f __md5hash.bin
|
||||
|
||||
# Remove hte unsigned binary
|
||||
# Remove the unsigned binary
|
||||
rm -f $BUILD/application.bin
|
||||
|
||||
exit $RET
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
#define WIPY_SD
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy-SD"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
#define WIPY
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
@@ -60,17 +60,20 @@ BOOT_MAIN_SRC_S = \
|
||||
bootmgr/runapp.s
|
||||
|
||||
BOOT_PY_SRC_C = $(addprefix py/,\
|
||||
pfenv.c \
|
||||
pfenv_printf.c \
|
||||
mpprint.c \
|
||||
)
|
||||
|
||||
BOOT_STM_SRC_C = $(addprefix stmhal/,\
|
||||
printf.c \
|
||||
string0.c \
|
||||
)
|
||||
|
||||
|
||||
BOOT_LIB_SRC_C = $(addprefix lib/,\
|
||||
libc/string0.c \
|
||||
)
|
||||
|
||||
OBJ = $(addprefix $(BUILD)/, $(BOOT_HAL_SRC_C:.c=.o) $(BOOT_SL_SRC_C:.c=.o) $(BOOT_CC3100_SRC_C:.c=.o) $(BOOT_UTIL_SRC_C:.c=.o) $(BOOT_MISC_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(BOOT_MAIN_SRC_C:.c=.o) $(BOOT_MAIN_SRC_S:.s=.o) $(BOOT_PY_SRC_C:.c=.o) $(BOOT_STM_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(BOOT_LIB_SRC_C:.c=.o))
|
||||
|
||||
# Add the linker script
|
||||
LINKER_SCRIPT = bootmgr/bootmgr.lds
|
||||
@@ -125,6 +128,6 @@ $(BUILD)/bootloader.bin: $(BUILD)/bootmgr.bin
|
||||
$(HEADER_BUILD)/qstrdefs.generated.h: | $(HEADER_BUILD)
|
||||
touch $@
|
||||
|
||||
# Create an empty "py-version.h" needed by py/mkrules.mk
|
||||
$(HEADER_BUILD)/py-version.h: | $(HEADER_BUILD)
|
||||
# Create an empty "mpversion.h" needed by py/mkrules.mk
|
||||
$(HEADER_BUILD)/mpversion.h: | $(HEADER_BUILD)
|
||||
touch $@
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <std.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -62,7 +62,7 @@
|
||||
#define BOOTMGR_HASH_SIZE 32
|
||||
#define BOOTMGR_BUFF_SIZE 512
|
||||
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_MS 1600
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_MS 1200
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS 200
|
||||
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_MS 800
|
||||
@@ -196,7 +196,7 @@ static bool bootmgr_verify (void) {
|
||||
}
|
||||
|
||||
// read the hash from the file and close it
|
||||
ASSERT (BOOTMGR_HASH_SIZE == sl_FsRead(fHandle, offset, bootmgr_file_buf, BOOTMGR_HASH_SIZE));
|
||||
sl_FsRead(fHandle, offset, bootmgr_file_buf, BOOTMGR_HASH_SIZE);
|
||||
sl_FsClose (fHandle, NULL, NULL, 0);
|
||||
bootmgr_file_buf[BOOTMGR_HASH_SIZE] = '\0';
|
||||
// compare both hashes
|
||||
@@ -347,3 +347,12 @@ int main (void) {
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! The following stub function is needed to link mp_vprintf
|
||||
//*****************************************************************************
|
||||
#include "py/qstr.h"
|
||||
|
||||
const byte *qstr_data(qstr q, mp_uint_t *len) {
|
||||
*len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
#include "sd_diskio.h" /* SDCARD disk IO API */
|
||||
#endif
|
||||
#include "modutime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "timeutils.h"
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define SFLASH 0 /* Map SFLASH drive to drive number 0 */
|
||||
@@ -192,13 +192,13 @@ DWORD get_fattime (
|
||||
void
|
||||
)
|
||||
{
|
||||
mod_struct_time tm;
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
// Get the time from the on-chip RTC and convert it to struct_time
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
|
||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/misc.h"
|
||||
@@ -38,7 +37,6 @@ extern BYTE ff_CurrVol;
|
||||
#endif
|
||||
|
||||
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
|
||||
stoupper ((char *)(*path));
|
||||
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
|
||||
if ((*path)[mount_point_len] == '/') {
|
||||
*path += mount_point_len;
|
||||
@@ -66,11 +64,11 @@ int ff_get_ldnumber (const TCHAR **path) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (check_path(path, "/SFLASH", 7)) {
|
||||
if (check_path(path, "/flash", 6)) {
|
||||
return 0;
|
||||
}
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
else if (check_path(path, "/SD", 3)) {
|
||||
else if (check_path(path, "/sd", 3)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -84,13 +82,13 @@ void ff_get_volname(BYTE vol, TCHAR **dest) {
|
||||
if (vol == 0)
|
||||
#endif
|
||||
{
|
||||
memcpy(*dest, "/SFLASH", 7);
|
||||
memcpy(*dest, "/flash", 6);
|
||||
*dest += 7;
|
||||
}
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
else
|
||||
{
|
||||
memcpy(*dest, "/SD", 3);
|
||||
memcpy(*dest, "/sd", 3);
|
||||
*dest += 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
/---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* Original file from:
|
||||
* FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* 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 _FFCONF
|
||||
#define _FFCONF 32020 /* Revision ID */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "py/mpconfig.h"
|
||||
@@ -8,8 +37,6 @@
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define _FFCONF 80376 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
@@ -24,9 +51,9 @@
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes basic writing API functions, f_write(),
|
||||
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
|
||||
/ f_getfree() and optional writing functions as well. */
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
@@ -48,9 +75,13 @@
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read feature and related functions,
|
||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_READONLY need to be set to 0. */
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
@@ -63,8 +94,8 @@
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
/* To enable it, also _FS_TINY need to be set to 1. */
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
@@ -75,32 +106,24 @@
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift_JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN (MICROPY_ENABLE_LFN)
|
||||
@@ -155,8 +178,8 @@
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
/* _STR_VOLUME_ID option switches string volume ID feature.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
@@ -169,7 +192,7 @@
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
@@ -206,9 +229,9 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 11
|
||||
#define _NORTC_MDAY 9
|
||||
#define _NORTC_YEAR 2014
|
||||
#define _NORTC_MON 2
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
@@ -274,3 +297,4 @@
|
||||
/ PIC32 0 H8/300H 0 8051 0/1
|
||||
*/
|
||||
|
||||
#endif // _FFCONF
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
@@ -134,7 +132,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
return pvPortMalloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +144,7 @@ void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Discard the memory block with POSIX API */
|
||||
vPortFree(mblock); /* Discard the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
#include <std.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "ftp.h"
|
||||
#include "simplelink.h"
|
||||
#include "modwlan.h"
|
||||
#include "modutime.h"
|
||||
#include "debug.h"
|
||||
#include "serverstask.h"
|
||||
#include "ff.h"
|
||||
@@ -49,6 +48,7 @@
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "updater.h"
|
||||
#include "timeutils.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
@@ -301,19 +301,21 @@ void ftp_run (void) {
|
||||
if (SOCKETFIFO_IsEmpty()) {
|
||||
uint32_t readsize;
|
||||
ftp_result_t result;
|
||||
ftp_data.ctimeout = 0;
|
||||
result = ftp_read_file ((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &readsize);
|
||||
if (readsize > 0 && result != E_FTP_RESULT_FAILED) {
|
||||
ftp_send_data(readsize);
|
||||
ftp_data.ctimeout = 0;
|
||||
if (result == E_FTP_RESULT_FAILED) {
|
||||
ftp_send_reply(451, NULL);
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
}
|
||||
else {
|
||||
if (readsize > 0) {
|
||||
ftp_send_data(readsize);
|
||||
}
|
||||
if (result == E_FTP_RESULT_OK) {
|
||||
ftp_send_reply(226, NULL);
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ftp_send_reply(451, NULL);
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case E_FTP_STE_CONTINUE_FILE_RX:
|
||||
@@ -433,7 +435,7 @@ static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||
|
||||
// Bind the socket to a port number
|
||||
sServerAddress.sin_family = AF_INET;
|
||||
sServerAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
sServerAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
sServerAddress.sin_port = htons(port);
|
||||
|
||||
ASSERT (sl_Bind(_sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress)) == SL_SOC_OK);
|
||||
@@ -588,8 +590,12 @@ static void ftp_process_cmd (void) {
|
||||
char *bufptr = (char *)ftp_cmd_buffer;
|
||||
ftp_result_t result;
|
||||
uint32_t listsize;
|
||||
FILINFO fno;
|
||||
FRESULT fres;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
ftp_data.closechild = false;
|
||||
// also use the reply buffer to receive new commands
|
||||
@@ -665,7 +671,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_USER:
|
||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||
if (!memcmp(ftp_scratch_buffer, servers_user, MAX(strlen(ftp_scratch_buffer), strlen(servers_user)))) {
|
||||
ftp_data.loggin.uservalid = true;
|
||||
ftp_data.loggin.uservalid = true && (strlen(servers_user) == strlen(ftp_scratch_buffer));
|
||||
}
|
||||
ftp_send_reply(331, NULL);
|
||||
break;
|
||||
@@ -673,12 +679,13 @@ static void ftp_process_cmd (void) {
|
||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||
if (!memcmp(ftp_scratch_buffer, servers_pass, MAX(strlen(ftp_scratch_buffer), strlen(servers_pass))) &&
|
||||
ftp_data.loggin.uservalid) {
|
||||
ftp_data.loggin.passvalid = true;
|
||||
ftp_send_reply(230, NULL);
|
||||
}
|
||||
else {
|
||||
ftp_send_reply(530, NULL);
|
||||
ftp_data.loggin.passvalid = true && (strlen(servers_pass) == strlen(ftp_scratch_buffer));
|
||||
if (ftp_data.loggin.passvalid) {
|
||||
ftp_send_reply(230, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ftp_send_reply(530, NULL);
|
||||
break;
|
||||
case E_FTP_CMD_PASV:
|
||||
{
|
||||
@@ -695,7 +702,7 @@ static void ftp_process_cmd (void) {
|
||||
ftp_data.dtimeout = 0;
|
||||
wlan_get_ip(&ip);
|
||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "(%u,%u,%u,%u,%u,%u)",
|
||||
pip[0], pip[1], pip[2], pip[3], (FTP_PASIVE_DATA_PORT >> 8), (FTP_PASIVE_DATA_PORT & 0xFF));
|
||||
pip[3], pip[2], pip[1], pip[0], (FTP_PASIVE_DATA_PORT >> 8), (FTP_PASIVE_DATA_PORT & 0xFF));
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_LISTEN_FOR_DATA;
|
||||
ftp_send_reply(227, (char *)ftp_data.dBuffer);
|
||||
}
|
||||
@@ -877,7 +884,7 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
|
||||
uint16_t mseconds;
|
||||
uint mindex = (((fno->fdate >> 5) & 0x0f) > 0) ? (((fno->fdate >> 5) & 0x0f) - 1) : 0;
|
||||
uint day = ((fno->fdate & 0x1f) > 0) ? (fno->fdate & 0x1f) : 1;
|
||||
uint fseconds = mod_time_seconds_since_2000(1980 + ((fno->fdate >> 9) & 0x7f),
|
||||
uint fseconds = timeutils_seconds_since_2000(1980 + ((fno->fdate >> 9) & 0x7f),
|
||||
(fno->fdate >> 5) & 0x0f,
|
||||
fno->fdate & 0x1f,
|
||||
(fno->ftime >> 11) & 0x1f,
|
||||
@@ -887,22 +894,30 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
|
||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
|
||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||
#if _USE_LFN
|
||||
1980 + ((fno->fdate >> 9) & 0x7f), *fno->lfname ? fno->lfname : fno->fname);
|
||||
#else
|
||||
1980 + ((fno->fdate >> 9) & 0x7f), fno->fname);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %02u:%02u %s\r\n",
|
||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||
#if _USE_LFN
|
||||
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, *fno->lfname ? fno->lfname : fno->fname);
|
||||
#else
|
||||
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, fno->fname);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
||||
mod_struct_time tm;
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t tseconds;
|
||||
uint16_t mseconds;
|
||||
char *type = "d";
|
||||
|
||||
mod_time_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
|
||||
timeutils_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
|
||||
|
||||
MAP_PRCMRTCGet(&tseconds, &mseconds);
|
||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - (FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101)) {
|
||||
@@ -956,10 +971,10 @@ static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint
|
||||
uint next = 0;
|
||||
// "hack" to list root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SFLASH");
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (sd_disk_ready()) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SD");
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "sd");
|
||||
}
|
||||
#endif
|
||||
*listsize = next;
|
||||
@@ -979,11 +994,18 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
uint next = 0;
|
||||
uint count = 0;
|
||||
FRESULT res;
|
||||
FILINFO fno;
|
||||
ftp_result_t result = E_FTP_RESULT_CONTINUE;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = mem_Malloc(_MAX_LFN);
|
||||
fno.lfsize = _MAX_LFN;
|
||||
|
||||
/* read up to 4 directory items */
|
||||
while (count++ < 4) {
|
||||
// read up to 2 directory items
|
||||
while (count < 2) {
|
||||
#else
|
||||
// read up to 4 directory items
|
||||
while (count < 4) {
|
||||
#endif
|
||||
res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
result = E_FTP_RESULT_OK;
|
||||
@@ -992,13 +1014,17 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
// Add the entry to the list
|
||||
// add the entry to the list
|
||||
next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
|
||||
count++;
|
||||
}
|
||||
if (result == E_FTP_RESULT_OK) {
|
||||
ftp_close_files();
|
||||
}
|
||||
*listsize = next;
|
||||
#if _USE_LFN
|
||||
mem_Free(fno.lfname);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -14,9 +13,9 @@
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define UPDATER_IMG_PATH "/SFLASH/SYS/MCUIMG.BIN"
|
||||
#define UPDATER_SRVPACK_PATH "/SFLASH/SYS/SRVPCK.UCF"
|
||||
#define UPDATER_SIGN_PATH "/SFLASH/SYS/SRVPCK.SIG"
|
||||
#define UPDATER_IMG_PATH "/flash/sys/mcuimg.bin"
|
||||
#define UPDATER_SRVPACK_PATH "/flash/sys/servicepack.ucf"
|
||||
#define UPDATER_SIGN_PATH "/flash/sys/servicepack.sig"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
@@ -37,8 +36,6 @@ static updater_data_t updater_data;
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
bool updater_check_path (void *path) {
|
||||
// conert the path supplied to upper case
|
||||
stoupper (path);
|
||||
if (!strcmp(UPDATER_IMG_PATH, path)) {
|
||||
updater_data.path = IMG_UPDATE;
|
||||
updater_data.fsize = IMG_SIZE;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
@@ -37,17 +37,6 @@
|
||||
#include "pybpin.h"
|
||||
#include MICROPY_HAL_H
|
||||
|
||||
STATIC void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_named_pins_obj_t *self = self_in;
|
||||
print(env, "<Pin.%s>", qstr_str(self->name));
|
||||
}
|
||||
|
||||
const mp_obj_type_t pin_cpu_pins_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_cpu,
|
||||
.print = pin_named_pins_obj_print,
|
||||
.locals_dict = (mp_obj_t)&pin_cpu_pins_locals_dict,
|
||||
};
|
||||
|
||||
pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
@@ -58,16 +47,6 @@ pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
if (((pin_obj_t *)named_map->table[i].value)->pin_num == pin_num) {
|
||||
return named_map->table[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -54,13 +54,11 @@ void mod_network_register_nic(mp_obj_t nic) {
|
||||
mp_obj_list_append(&MP_STATE_PORT(mod_network_nic_list), nic);
|
||||
}
|
||||
|
||||
mp_obj_t mod_network_find_nic(const uint8_t *ip) {
|
||||
// find a NIC that is suited to given IP address
|
||||
mp_obj_t mod_network_find_nic(void) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
||||
return nic;
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
@@ -116,65 +114,3 @@ const mp_obj_module_t mp_module_network = {
|
||||
.name = MP_QSTR_network,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_network_globals,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
// Miscellaneous helpers
|
||||
|
||||
void mod_network_convert_ipv4_endianness(uint8_t *ip) {
|
||||
uint8_t ip0 = ip[0]; ip[0] = ip[3]; ip[3] = ip0;
|
||||
uint8_t ip1 = ip[1]; ip[1] = ip[2]; ip[2] = ip1;
|
||||
}
|
||||
|
||||
// Takes an address of the form '192.168.0.1' and converts it to network format
|
||||
// in out_ip (big endian, so the 192 is the first byte).
|
||||
void mod_network_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip) {
|
||||
mp_uint_t addr_len;
|
||||
const char *addr_str = mp_obj_str_get_data(addr_in, &addr_len);
|
||||
if (addr_len == 0) {
|
||||
// special case of no address given
|
||||
memset(out_ip, 0, MOD_NETWORK_IPV4ADDR_BUF_SIZE);
|
||||
return;
|
||||
}
|
||||
const char *s = addr_str;
|
||||
const char *s_top = addr_str + addr_len;
|
||||
for (mp_uint_t i = 0;; i++) {
|
||||
mp_uint_t val = 0;
|
||||
for (; s < s_top && *s != '.'; s++) {
|
||||
val = val * 10 + *s - '0';
|
||||
}
|
||||
out_ip[i] = val;
|
||||
if (i == 3 && s == s_top) {
|
||||
return;
|
||||
} else if (i < 3 && s < s_top && *s == '.') {
|
||||
s++;
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Takes an address of the form ('192.168.0.1', 8080), returns the port and
|
||||
// puts IP in out_ip (which must take at least IPADDR_BUF_SIZE bytes).
|
||||
mp_uint_t mod_network_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip) {
|
||||
mp_obj_t *addr_items;
|
||||
mp_obj_get_array_fixed_n(addr_in, 2, &addr_items);
|
||||
mod_network_parse_ipv4_addr(addr_items[0], out_ip);
|
||||
return mp_obj_get_int(addr_items[1]);
|
||||
}
|
||||
|
||||
// Takes an array with a raw IPv4 address and returns something like '192.168.0.1'.
|
||||
mp_obj_t mod_network_format_ipv4_addr(uint8_t *ip) {
|
||||
char ip_str[16];
|
||||
mp_uint_t ip_len = snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
return mp_obj_new_str(ip_str, ip_len, false);
|
||||
}
|
||||
|
||||
// Takes an array with a raw IP address, and a port, and returns a net-address
|
||||
// tuple such as ('192.168.0.1', 8080).
|
||||
mp_obj_t mod_network_format_inet_addr(uint8_t *ip, mp_uint_t port) {
|
||||
mp_obj_t tuple[2] = {
|
||||
tuple[0] = mod_network_format_ipv4_addr(ip),
|
||||
tuple[1] = mp_obj_new_int(port),
|
||||
};
|
||||
return mp_obj_new_tuple(2, tuple);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODNETWORK_H_
|
||||
#define MODNETWORK_H_
|
||||
|
||||
#define MOD_NETWORK_IPV4ADDR_BUF_SIZE (4)
|
||||
|
||||
// Forward declaration
|
||||
@@ -72,10 +75,6 @@ extern const mod_network_nic_type_t mod_network_nic_type_wlan;
|
||||
|
||||
void mod_network_init0(void);
|
||||
void mod_network_register_nic(mp_obj_t nic);
|
||||
mp_obj_t mod_network_find_nic(const uint8_t *ip);
|
||||
mp_obj_t mod_network_find_nic(void);
|
||||
|
||||
void mod_network_convert_ipv4_endianness(uint8_t *ip);
|
||||
void mod_network_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip);
|
||||
mp_uint_t mod_network_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip);
|
||||
mp_obj_t mod_network_format_ipv4_addr(uint8_t *ip);
|
||||
mp_obj_t mod_network_format_inet_addr(uint8_t *ip, mp_uint_t port);
|
||||
#endif // MODNETWORK_H_
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
@@ -66,6 +65,7 @@
|
||||
#include "utils.h"
|
||||
#include "gccollect.h"
|
||||
#include "mperror.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -233,17 +233,6 @@ STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart);
|
||||
|
||||
/// \function mkdisk('path')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair
|
||||
STATIC mp_obj_t pyb_mkdisk(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
if (FR_OK != f_mkfs(path, 1, 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_mkdisk_obj, pyb_mkdisk);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
|
||||
|
||||
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
@@ -268,8 +257,6 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_micros), (mp_obj_t)&pyb_elapsed_micros_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&pyb_mkdisk_obj },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
|
||||
|
||||
@@ -27,19 +27,22 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "file.h"
|
||||
#include "modutime.h"
|
||||
#include "random.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "mpexception.h"
|
||||
#include "version.h"
|
||||
#include "timeutils.h"
|
||||
|
||||
/// \module os - basic "operating system" services
|
||||
///
|
||||
@@ -48,12 +51,15 @@
|
||||
/// The filesystem has `/` as the root directory, and the available physical
|
||||
/// drives are accessible from here. They are currently:
|
||||
///
|
||||
/// /SFLASH -- the serial flash filesystem
|
||||
/// /SD -- the SD card (if it exists)
|
||||
/// /flash -- the serial flash filesystem
|
||||
/// /sd -- the SD card (if it exists)
|
||||
///
|
||||
/// On boot up, the current directory is `/SFLASH` if no SD card is inserted,
|
||||
/// otherwise it is `/SD`.
|
||||
/// On boot up, the current directory is `/flash` if no SD card is inserted,
|
||||
/// otherwise it is `/sd`.
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC bool sd_in_root(void) {
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
return sd_disk_ready();
|
||||
@@ -62,6 +68,35 @@ STATIC bool sd_in_root(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
//
|
||||
|
||||
STATIC const qstr os_uname_info_fields[] = {
|
||||
MP_QSTR_sysname, MP_QSTR_nodename,
|
||||
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
|
||||
};
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, WIPY_SW_VERSION_NUMBER);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||
STATIC MP_DEFINE_ATTRTUPLE(
|
||||
os_uname_info_obj,
|
||||
os_uname_info_fields,
|
||||
5,
|
||||
(mp_obj_t)&os_uname_info_sysname_obj,
|
||||
(mp_obj_t)&os_uname_info_nodename_obj,
|
||||
(mp_obj_t)&os_uname_info_release_obj,
|
||||
(mp_obj_t)&os_uname_info_version_obj,
|
||||
(mp_obj_t)&os_uname_info_machine_obj
|
||||
);
|
||||
|
||||
STATIC mp_obj_t os_uname(void) {
|
||||
return (mp_obj_t)&os_uname_info_obj;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
|
||||
|
||||
/// \function chdir(path)
|
||||
/// Change current directory.
|
||||
STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
@@ -73,10 +108,9 @@ STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
if (res == FR_OK) {
|
||||
res = f_chdir(path);
|
||||
}
|
||||
// TODO: Warn if too many open files...
|
||||
|
||||
if (res != FR_OK) {
|
||||
// TODO should be mp_type_FileNotFoundError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
@@ -102,6 +136,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
|
||||
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
bool is_str_type = true;
|
||||
const char *path;
|
||||
|
||||
if (n_args == 1) {
|
||||
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
|
||||
is_str_type = false;
|
||||
@@ -114,21 +149,25 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// "hack" to list root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_SFLASH));
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_flash));
|
||||
if (sd_in_root()) {
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_SD));
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
|
||||
}
|
||||
return dir_list;
|
||||
}
|
||||
|
||||
FRESULT res;
|
||||
FILINFO fno;
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
char lfn_buf[_MAX_LFN + 1];
|
||||
fno.lfname = lfn_buf;
|
||||
fno.lfsize = sizeof(lfn_buf);
|
||||
#endif
|
||||
|
||||
res = f_opendir(&dir, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
// TODO should be mp_type_FileNotFoundError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
@@ -139,7 +178,11 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
#if _USE_LFN
|
||||
char *fn = *fno.lfname ? fno.lfname : fno.fname;
|
||||
#else
|
||||
char *fn = fno.fname;
|
||||
#endif
|
||||
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
@@ -168,44 +211,28 @@ STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
case FR_EXIST:
|
||||
// TODO should be FileExistsError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
||||
|
||||
/// \function remove(path)
|
||||
/// Remove a file.
|
||||
/// Remove a file or a directory
|
||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
// TODO check that path is actually a file before trying to unlink it
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
||||
|
||||
/// \function rmdir(path)
|
||||
/// Remove a directory.
|
||||
STATIC mp_obj_t os_rmdir(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
// TODO check that path is actually a directory before trying to unlink it
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
// path_equal(/flash//, /flash) -> true
|
||||
@@ -225,14 +252,18 @@ STATIC bool path_equal(const char *path, const char *path_canonical) {
|
||||
/// Get the status of a file or directory.
|
||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
stoupper((char *)path);
|
||||
|
||||
FILINFO fno;
|
||||
FRESULT res;
|
||||
if (path_equal(path, "/") || path_equal(path, "/SFLASH") || path_equal(path, "/SD")) {
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
if (path_equal(path, "/") || path_equal(path, "/flash") || path_equal(path, "/sd")) {
|
||||
// stat built-in directory
|
||||
if (path[1] == 'S' && !sd_in_root()) {
|
||||
// no /SD directory
|
||||
if (path[1] == 's' && !sd_in_root()) {
|
||||
// no /sd directory
|
||||
res = FR_NO_PATH;
|
||||
goto error;
|
||||
}
|
||||
@@ -254,7 +285,7 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
} else {
|
||||
mode |= 0x8000; // stat.S_IFREG
|
||||
}
|
||||
mp_int_t seconds = mod_time_seconds_since_2000(
|
||||
mp_int_t seconds = timeutils_seconds_since_2000(
|
||||
1980 + ((fno.fdate >> 9) & 0x7f),
|
||||
(fno.fdate >> 5) & 0x0f,
|
||||
fno.fdate & 0x1f,
|
||||
@@ -282,11 +313,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
/// \function sync()
|
||||
/// Sync all filesystems.
|
||||
mp_obj_t os_sync(void) {
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \function urandom(n)
|
||||
@@ -304,26 +335,37 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
#endif
|
||||
|
||||
/// \function mkdisk('path')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair
|
||||
STATIC mp_obj_t os_mkdisk(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
if (FR_OK != f_mkfs(path, 1, 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdisk_obj, os_mkdisk);
|
||||
|
||||
STATIC const mp_map_elem_t os_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uname), (mp_obj_t)&os_uname_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&os_mkdisk_obj },
|
||||
|
||||
/// \constant sep - separation character used in paths
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODUTIME_H_
|
||||
#define MODUTIME_H_
|
||||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(os_sync_obj);
|
||||
|
||||
#endif // MODUTIME_H_
|
||||
#endif // MODUOS_H_
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -33,6 +32,7 @@
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/runtime.h"
|
||||
#include "netutils.h"
|
||||
#include "modnetwork.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
@@ -41,6 +41,18 @@
|
||||
|
||||
STATIC const mp_obj_type_t socket_type;
|
||||
|
||||
STATIC void socket_select_nic(mod_network_socket_obj_t *self) {
|
||||
// select a nic
|
||||
self->nic = mod_network_find_nic();
|
||||
self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic);
|
||||
|
||||
// call the nic to open the socket
|
||||
int _errno;
|
||||
if (self->nic_type->socket(self, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
}
|
||||
}
|
||||
|
||||
// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
|
||||
STATIC mp_obj_t socket_make_new(mp_obj_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, 4, false);
|
||||
@@ -66,22 +78,12 @@ STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
socket_select_nic(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) {
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// select NIC based on IP
|
||||
self->nic = mod_network_find_nic(ip);
|
||||
self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic);
|
||||
|
||||
// call the NIC to open the socket
|
||||
int _errno;
|
||||
if (self->nic_type->socket(self, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
}
|
||||
}
|
||||
}
|
||||
// method socket.close()
|
||||
STATIC mp_obj_t socket_close(mp_obj_t self_in) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
@@ -98,10 +100,7 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// call the NIC to bind the socket
|
||||
int _errno;
|
||||
@@ -157,7 +156,7 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
|
||||
// make the return value
|
||||
mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
|
||||
client->items[0] = socket2;
|
||||
client->items[1] = mod_network_format_inet_addr(ip, port);
|
||||
client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_LITTLE);
|
||||
|
||||
return client;
|
||||
}
|
||||
@@ -169,10 +168,7 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// call the NIC to connect the socket
|
||||
int _errno;
|
||||
@@ -236,10 +232,7 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// call the NIC to sendto
|
||||
int _errno;
|
||||
@@ -276,7 +269,7 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
vstr.buf[vstr.len] = '\0';
|
||||
tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
tuple[1] = mod_network_format_inet_addr(ip, port);
|
||||
tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_LITTLE);
|
||||
return mp_obj_new_tuple(2, tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom);
|
||||
@@ -292,7 +285,7 @@ STATIC mp_obj_t socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
mp_uint_t optlen;
|
||||
mp_int_t val;
|
||||
if (mp_obj_is_integer(args[3])) {
|
||||
val = mp_obj_int_get_truncated(args[3]);
|
||||
val = mp_obj_get_int_truncated(args[3]);
|
||||
optval = &val;
|
||||
optlen = sizeof(val);
|
||||
} else {
|
||||
@@ -407,7 +400,7 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||
tuple->items[4] = mod_network_format_inet_addr(out_ip, port);
|
||||
tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_LITTLE);
|
||||
return mp_obj_new_list(1, (mp_obj_t*)&tuple);
|
||||
}
|
||||
}
|
||||
@@ -430,6 +423,7 @@ STATIC const mp_map_elem_t mp_module_usocket_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(SOCK_DGRAM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(SOCK_RAW) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_SEC), MP_OBJ_NEW_SMALL_INT(SL_SEC_SOCKET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_TCP), MP_OBJ_NEW_SMALL_INT(IPPROTO_TCP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(IPPROTO_UDP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_RAW), MP_OBJ_NEW_SMALL_INT(IPPROTO_RAW) },
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "modutime.h"
|
||||
#include "timeutils.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@@ -41,126 +41,11 @@
|
||||
#include "pybrtc.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
|
||||
// LEAPOCH corresponds to 2000-03-01, which is a mod-400 year, immediately
|
||||
// after Feb 29. We calculate seconds as a signed integer relative to that.
|
||||
//
|
||||
// Our timebase is relative to 2000-01-01.
|
||||
|
||||
#define LEAPOCH ((31 + 29) * 86400)
|
||||
|
||||
#define DAYS_PER_400Y (365*400 + 97)
|
||||
#define DAYS_PER_100Y (365*100 + 24)
|
||||
#define DAYS_PER_4Y (365*4 + 1)
|
||||
|
||||
|
||||
/// \module time - time related functions
|
||||
///
|
||||
/// The `time` module provides functions for getting the current time and date,
|
||||
/// and for sleeping.
|
||||
|
||||
STATIC const uint16_t days_since_jan1[]= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
|
||||
|
||||
STATIC bool is_leap_year(mp_uint_t year) {
|
||||
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
|
||||
}
|
||||
|
||||
// Month is one based
|
||||
STATIC mp_uint_t mod_time_days_in_month(mp_uint_t year, mp_uint_t month) {
|
||||
mp_uint_t mdays = days_since_jan1[month] - days_since_jan1[month - 1];
|
||||
if (month == 2 && is_leap_year(year)) {
|
||||
mdays++;
|
||||
}
|
||||
return mdays;
|
||||
}
|
||||
|
||||
// compute the day of the year, between 1 and 366
|
||||
// month should be between 1 and 12, date should start at 1
|
||||
STATIC mp_uint_t mod_time_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date) {
|
||||
mp_uint_t yday = days_since_jan1[month - 1] + date;
|
||||
if (month >= 3 && is_leap_year(year)) {
|
||||
yday += 1;
|
||||
}
|
||||
return yday;
|
||||
}
|
||||
|
||||
// returns the number of seconds, as an integer, since 2000-01-01
|
||||
mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) {
|
||||
return
|
||||
second
|
||||
+ minute * 60
|
||||
+ hour * 3600
|
||||
+ (mod_time_year_day(year, month, date) - 1
|
||||
+ ((year - 2000 + 3) / 4) // add a day each 4 years starting with 2001
|
||||
- ((year - 2000 + 99) / 100) // subtract a day each 100 years starting with 2001
|
||||
+ ((year - 2000 + 399) / 400) // add a day each 400 years starting with 2001
|
||||
) * 86400
|
||||
+ (year - 2000) * 31536000;
|
||||
}
|
||||
|
||||
void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm) {
|
||||
// The following algorithm was adapted from musl's __secs_to_tm and adapted
|
||||
// for differences in Micro Python's timebase.
|
||||
|
||||
mp_int_t seconds = t - LEAPOCH;
|
||||
|
||||
mp_int_t days = seconds / 86400;
|
||||
seconds %= 86400;
|
||||
tm->tm_hour = seconds / 3600;
|
||||
tm->tm_min = seconds / 60 % 60;
|
||||
tm->tm_sec = seconds % 60;
|
||||
|
||||
mp_int_t wday = (days + 2) % 7; // Mar 1, 2000 was a Wednesday (2)
|
||||
if (wday < 0) {
|
||||
wday += 7;
|
||||
}
|
||||
tm->tm_wday = wday;
|
||||
|
||||
mp_int_t qc_cycles = days / DAYS_PER_400Y;
|
||||
days %= DAYS_PER_400Y;
|
||||
if (days < 0) {
|
||||
days += DAYS_PER_400Y;
|
||||
qc_cycles--;
|
||||
}
|
||||
mp_int_t c_cycles = days / DAYS_PER_100Y;
|
||||
if (c_cycles == 4) {
|
||||
c_cycles--;
|
||||
}
|
||||
days -= (c_cycles * DAYS_PER_100Y);
|
||||
|
||||
mp_int_t q_cycles = days / DAYS_PER_4Y;
|
||||
if (q_cycles == 25) {
|
||||
q_cycles--;
|
||||
}
|
||||
days -= q_cycles * DAYS_PER_4Y;
|
||||
|
||||
mp_int_t years = days / 365;
|
||||
if (years == 4) {
|
||||
years--;
|
||||
}
|
||||
days -= (years * 365);
|
||||
|
||||
tm->tm_year = 2000 + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles;
|
||||
|
||||
// Note: days_in_month[0] corresponds to March
|
||||
STATIC const int8_t days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29};
|
||||
|
||||
mp_int_t month;
|
||||
for (month = 0; days_in_month[month] <= days; month++) {
|
||||
days -= days_in_month[month];
|
||||
}
|
||||
|
||||
tm->tm_mon = month + 2;
|
||||
if (tm->tm_mon >= 12) {
|
||||
tm->tm_mon -= 12;
|
||||
tm->tm_year++;
|
||||
}
|
||||
tm->tm_mday = days + 1; // Make one based
|
||||
tm->tm_mon++; // Make one based
|
||||
|
||||
tm->tm_yday = mod_time_year_day(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||
}
|
||||
|
||||
/// \function localtime([secs])
|
||||
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
|
||||
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
|
||||
@@ -175,14 +60,14 @@ void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm
|
||||
/// yearday is 1-366
|
||||
STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0 || args[0] == mp_const_none) {
|
||||
mod_struct_time tm;
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mseconds = RTC_CYCLES_U16MS(mseconds);
|
||||
mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
@@ -197,8 +82,8 @@ STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
} else {
|
||||
mp_int_t seconds = mp_obj_get_int(args[0]);
|
||||
mod_struct_time tm;
|
||||
mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
mp_obj_t tuple[8] = {
|
||||
tuple[0] = mp_obj_new_int(tm.tm_year),
|
||||
tuple[1] = mp_obj_new_int(tm.tm_mon),
|
||||
@@ -231,64 +116,10 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
mp_int_t year = mp_obj_get_int(elem[0]);
|
||||
mp_int_t month = mp_obj_get_int(elem[1]);
|
||||
mp_int_t mday = mp_obj_get_int(elem[2]);
|
||||
mp_int_t hours = mp_obj_get_int(elem[3]);
|
||||
mp_int_t minutes = mp_obj_get_int(elem[4]);
|
||||
mp_int_t seconds = mp_obj_get_int(elem[5]);
|
||||
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
|
||||
mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]),
|
||||
mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
|
||||
|
||||
// Normalize the tuple. This allows things like:
|
||||
//
|
||||
// tm_tomorrow = list(time.localtime())
|
||||
// tm_tomorrow[2] += 1 # Adds 1 to mday
|
||||
// tomorrow = time.mktime(tm_tommorrow)
|
||||
//
|
||||
// And not have to worry about all the weird overflows.
|
||||
//
|
||||
// You can subtract dates/times this way as well.
|
||||
|
||||
minutes += seconds / 60;
|
||||
if ((seconds = seconds % 60) < 0) {
|
||||
seconds += 60;
|
||||
minutes--;
|
||||
}
|
||||
|
||||
hours += minutes / 60;
|
||||
if ((minutes = minutes % 60) < 0) {
|
||||
minutes += 60;
|
||||
hours--;
|
||||
}
|
||||
|
||||
mday += hours / 24;
|
||||
if ((hours = hours % 24) < 0) {
|
||||
hours += 24;
|
||||
mday--;
|
||||
}
|
||||
|
||||
month--; // make month zero based
|
||||
year += month / 12;
|
||||
if ((month = month % 12) < 0) {
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
month++; // back to one based
|
||||
|
||||
while (mday < 1) {
|
||||
if (--month == 0) {
|
||||
month = 12;
|
||||
year--;
|
||||
}
|
||||
mday += mod_time_days_in_month(year, month);
|
||||
}
|
||||
while (mday > mod_time_days_in_month(year, month)) {
|
||||
mday -= mod_time_days_in_month(year, month);
|
||||
if (++month == 13) {
|
||||
month = 1;
|
||||
year++;
|
||||
}
|
||||
}
|
||||
return mp_obj_new_int_from_uint(mod_time_seconds_since_2000(year, month, mday, hours, minutes, seconds));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
|
||||
|
||||
|
||||
@@ -24,15 +24,17 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "std.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "simplelink.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "netutils.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "pybioctl.h"
|
||||
@@ -94,6 +96,8 @@ typedef struct _wlan_obj_t {
|
||||
uint8_t ssid[33];
|
||||
uint8_t bssid[6];
|
||||
|
||||
uint8_t staconnected;
|
||||
|
||||
} wlan_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
@@ -130,21 +134,23 @@ typedef struct _wlan_obj_t {
|
||||
#define WLAN_MAX_RX_SIZE 16000
|
||||
#define WLAN_MAX_TX_SIZE 1476
|
||||
|
||||
#define MODWLAN_IP_MODE_DYNAMIC 0
|
||||
#define MODWLAN_IP_MODE_STATIC 1
|
||||
|
||||
#define MAKE_SOCKADDR(addr, ip, port) sockaddr addr; \
|
||||
addr.sa_family = AF_INET; \
|
||||
addr.sa_data[0] = port >> 8; \
|
||||
addr.sa_data[1] = port; \
|
||||
addr.sa_data[2] = ip[0]; \
|
||||
addr.sa_data[3] = ip[1]; \
|
||||
addr.sa_data[4] = ip[2]; \
|
||||
addr.sa_data[5] = ip[3];
|
||||
addr.sa_data[2] = ip[3]; \
|
||||
addr.sa_data[3] = ip[2]; \
|
||||
addr.sa_data[4] = ip[1]; \
|
||||
addr.sa_data[5] = ip[0];
|
||||
|
||||
#define UNPACK_SOCKADDR(addr, ip, port) port = (addr.sa_data[0] << 8) | addr.sa_data[1]; \
|
||||
ip[0] = addr.sa_data[2]; \
|
||||
ip[1] = addr.sa_data[3]; \
|
||||
ip[2] = addr.sa_data[4]; \
|
||||
ip[3] = addr.sa_data[5];
|
||||
ip[0] = addr.sa_data[5]; \
|
||||
ip[1] = addr.sa_data[4]; \
|
||||
ip[2] = addr.sa_data[3]; \
|
||||
ip[3] = addr.sa_data[2];
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
@@ -162,6 +168,7 @@ STATIC wlan_obj_t wlan_obj = {
|
||||
.ssid = {0},
|
||||
.bssid = {0},
|
||||
.mac = {0},
|
||||
.staconnected = 0
|
||||
};
|
||||
|
||||
STATIC const mp_cb_methods_t wlan_cb_methods;
|
||||
@@ -176,11 +183,14 @@ OsiLockObj_t wlan_LockObj;
|
||||
******************************************************************************/
|
||||
STATIC void wlan_initialize_data (void);
|
||||
STATIC void wlan_reenable (SlWlanMode_t mode);
|
||||
STATIC void wlan_servers_start (void);
|
||||
STATIC void wlan_servers_stop (void);
|
||||
STATIC void wlan_get_sl_mac (void);
|
||||
STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
|
||||
const char* key, uint32_t key_len);
|
||||
STATIC void wlan_lpds_callback_enable (mp_obj_t self_in);
|
||||
STATIC void wlan_lpds_callback_disable (mp_obj_t self_in);
|
||||
STATIC bool wlan_scan_result_is_unique (const mp_obj_list_t *nets, _u8 *bssid);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
@@ -219,10 +229,12 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) {
|
||||
}
|
||||
break;
|
||||
case SL_WLAN_STA_CONNECTED_EVENT:
|
||||
// TODO
|
||||
wlan_obj.staconnected++;
|
||||
break;
|
||||
case SL_WLAN_STA_DISCONNECTED_EVENT:
|
||||
// TODO
|
||||
if (wlan_obj.staconnected > 0) {
|
||||
wlan_obj.staconnected--;
|
||||
}
|
||||
break;
|
||||
case SL_WLAN_P2P_DEV_FOUND_EVENT:
|
||||
// TODO
|
||||
@@ -265,9 +277,9 @@ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) {
|
||||
pEventData = &pNetAppEvent->EventData.ipAcquiredV4;
|
||||
|
||||
// Get ip, gateway and dns
|
||||
wlan_obj.gateway = ntohl(pEventData->gateway);
|
||||
wlan_obj.ip = ntohl(pEventData->ip);
|
||||
wlan_obj.dns = ntohl(pEventData->dns);
|
||||
wlan_obj.gateway = pEventData->gateway;
|
||||
wlan_obj.ip = pEventData->ip;
|
||||
wlan_obj.dns = pEventData->dns;
|
||||
}
|
||||
break;
|
||||
case SL_NETAPP_IPV6_IPACQUIRED_EVENT:
|
||||
@@ -321,8 +333,6 @@ void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) {
|
||||
if (!pDevEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT (false);
|
||||
}
|
||||
|
||||
|
||||
@@ -370,16 +380,15 @@ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) {
|
||||
// SimpleLink Asynchronous Event Handlers -- End
|
||||
//*****************************************************************************
|
||||
|
||||
void wlan_init0 (void) {
|
||||
__attribute__ ((section (".boot")))
|
||||
void wlan_pre_init (void) {
|
||||
// create the wlan lock
|
||||
ASSERT(OSI_OK == sl_LockObjCreate(&wlan_LockObj, "WlanLock"));
|
||||
}
|
||||
|
||||
void wlan_first_start (void) {
|
||||
// clear wlan data after checking any of the status flags
|
||||
wlan_initialize_data();
|
||||
|
||||
if (wlan_obj.mode < 0) {
|
||||
wlan_initialize_data();
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
}
|
||||
@@ -392,14 +401,10 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
const char *key, uint8_t key_len, uint8_t channel) {
|
||||
|
||||
if (mode == ROLE_STA || mode == ROLE_AP || mode == ROLE_P2P) {
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// Stop all other processes using the wlan engine
|
||||
if ((wlan_obj.servers_enabled = servers_are_enabled())) {
|
||||
servers_stop();
|
||||
}
|
||||
#endif
|
||||
// stop the servers
|
||||
wlan_servers_stop();
|
||||
|
||||
// do a basic start fisrt
|
||||
// do a basic start
|
||||
wlan_first_start();
|
||||
|
||||
// Device in station-mode. Disconnect previous connection if any
|
||||
@@ -408,10 +413,8 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
// other return-codes
|
||||
if (0 == sl_WlanDisconnect()) {
|
||||
while (IS_CONNECTED (wlan_obj.status)) {
|
||||
#ifndef SL_PLATFORM_MULTI_THREADED
|
||||
_SlTaskEntry();
|
||||
#endif
|
||||
HAL_Delay (5);
|
||||
wlan_update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,10 +457,21 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE, 2, country));
|
||||
ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, (_u8 *)&channel));
|
||||
|
||||
// Stop and start again
|
||||
// stop and start again
|
||||
wlan_reenable(mode);
|
||||
ASSERT (wlan_obj.mode == mode);
|
||||
|
||||
SlNetCfgIpV4Args_t ipV4;
|
||||
ipV4.ipV4 = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 IP address
|
||||
ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this AP
|
||||
ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 Default gateway address
|
||||
ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 DNS server address
|
||||
ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4,
|
||||
sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4));
|
||||
|
||||
// stop and start again
|
||||
wlan_reenable(mode);
|
||||
|
||||
SlNetAppDhcpServerBasicOpt_t dhcpParams;
|
||||
dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address
|
||||
dhcpParams.ipv4_addr_start = SL_IPV4_VAL(192,168,1,2); // first IP Address for allocation.
|
||||
@@ -467,16 +481,9 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
sizeof(SlNetAppDhcpServerBasicOpt_t), (_u8* )&dhcpParams)); // set parameters
|
||||
ASSERT_ON_ERROR(sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID)); // Start DHCP server with new settings
|
||||
|
||||
SlNetCfgIpV4Args_t ipV4;
|
||||
ipV4.ipV4 = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 IP address
|
||||
ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this AP
|
||||
ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 Default gateway address
|
||||
ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 DNS server address
|
||||
ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4,
|
||||
sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4));
|
||||
|
||||
// Stop and start again
|
||||
// stop and start again
|
||||
wlan_reenable(mode);
|
||||
|
||||
// save the security type
|
||||
wlan_obj.security = sec;
|
||||
}
|
||||
@@ -487,15 +494,11 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
ASSERT_ON_ERROR(sl_WlanSetMode(mode));
|
||||
// stop and start again
|
||||
wlan_reenable(mode);
|
||||
// set connection policy to Auto + SmartConfig (Device's default connection policy)
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0));
|
||||
// set connection policy to Auto + Fast (tries to connect to the last connected AP)
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_CONNECTION,SL_CONNECTION_POLICY(1, 1, 0, 0, 0), NULL, 0));
|
||||
}
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// Start the servers again
|
||||
if (wlan_obj.servers_enabled) {
|
||||
servers_start();
|
||||
}
|
||||
#endif
|
||||
// start the servers before returning
|
||||
wlan_servers_start();
|
||||
return MODWLAN_OK;
|
||||
}
|
||||
return MODWLAN_ERROR_INVALID_PARAMS;
|
||||
@@ -508,12 +511,7 @@ void wlan_update(void) {
|
||||
}
|
||||
|
||||
void wlan_stop (uint32_t timeout) {
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// Stop all other processes using the wlan engine
|
||||
if ((wlan_obj.servers_enabled = servers_are_enabled())) {
|
||||
servers_stop();
|
||||
}
|
||||
#endif
|
||||
wlan_servers_stop();
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
sl_Stop(timeout);
|
||||
wlan_obj.mode = -1;
|
||||
@@ -522,12 +520,7 @@ void wlan_stop (uint32_t timeout) {
|
||||
void wlan_start (void) {
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// start the servers if they were enabled before
|
||||
if (wlan_obj.servers_enabled) {
|
||||
servers_start();
|
||||
}
|
||||
#endif
|
||||
wlan_servers_start();
|
||||
}
|
||||
|
||||
void wlan_get_mac (uint8_t *macAddress) {
|
||||
@@ -552,6 +545,7 @@ STATIC void wlan_initialize_data (void) {
|
||||
wlan_obj.gateway = 0;
|
||||
wlan_obj.ip = 0;
|
||||
wlan_obj.security = SL_SEC_TYPE_OPEN;
|
||||
wlan_obj.staconnected = 0;
|
||||
memset(wlan_obj.ssid, 0, sizeof(wlan_obj.ssid));
|
||||
memset(wlan_obj.bssid, 0, sizeof(wlan_obj.bssid));
|
||||
}
|
||||
@@ -560,11 +554,30 @@ STATIC void wlan_reenable (SlWlanMode_t mode) {
|
||||
// stop and start again
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
sl_Stop(SL_STOP_TIMEOUT);
|
||||
wlan_initialize_data();
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
ASSERT (wlan_obj.mode == mode);
|
||||
}
|
||||
|
||||
STATIC void wlan_servers_start (void) {
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// start the servers if they were enabled before
|
||||
if (wlan_obj.servers_enabled) {
|
||||
servers_start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void wlan_servers_stop (void) {
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// Stop all other processes using the wlan engine
|
||||
if ((wlan_obj.servers_enabled = servers_are_enabled())) {
|
||||
servers_stop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
|
||||
const char* key, uint32_t key_len) {
|
||||
SlSecParams_t secParams;
|
||||
@@ -576,10 +589,8 @@ STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, co
|
||||
// Wait for the WLAN Event
|
||||
uint32_t waitForConnectionMs = 0;
|
||||
while (!IS_CONNECTED(wlan_obj.status)) {
|
||||
#ifndef SL_PLATFORM_MULTI_THREADED
|
||||
_SlTaskEntry();
|
||||
#endif
|
||||
HAL_Delay (5);
|
||||
wlan_update();
|
||||
if (++waitForConnectionMs >= MODWLAN_TIMEOUT_MS) {
|
||||
return MODWLAN_ERROR_TIMEOUT;
|
||||
}
|
||||
@@ -648,6 +659,17 @@ STATIC void wlan_lpds_callback_disable (mp_obj_t self_in) {
|
||||
pybsleep_set_wlan_lpds_callback (NULL);
|
||||
}
|
||||
|
||||
STATIC bool wlan_scan_result_is_unique (const mp_obj_list_t *nets, _u8 *bssid) {
|
||||
for (int i = 0; i < nets->len; i++) {
|
||||
// index 1 in the list is the bssid
|
||||
mp_obj_str_t *_bssid = (mp_obj_str_t *)((mp_obj_tuple_t *)nets->items[i])->items[1];
|
||||
if (!memcmp (_bssid->data, bssid, SL_BSSID_LENGTH)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings; WLAN class
|
||||
|
||||
@@ -689,19 +711,19 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
|
||||
return &wlan_obj;
|
||||
}
|
||||
|
||||
STATIC void wlan_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void wlan_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
wlan_obj_t *self = self_in;
|
||||
print(env, "<WLAN, mode=%u", self->mode);
|
||||
mp_printf(print, "<WLAN, mode=%u", self->mode);
|
||||
|
||||
// only print the bssid if in station mode
|
||||
if (self->mode != ROLE_AP && GET_STATUS_BIT(self->status, STATUS_BIT_CONNECTION)) {
|
||||
print(env, ", connected to: ssid=%s, bssid=%02x:%02x:%02x:%02x:%02x:%02x", self->ssid,
|
||||
mp_printf(print, ", connected to: ssid=%s, bssid=%02x:%02x:%02x:%02x:%02x:%02x", self->ssid,
|
||||
self->bssid[0], self->bssid[1], self->bssid[2], self->bssid[3], self->bssid[4], self->bssid[5]);
|
||||
}
|
||||
else {
|
||||
print(env, ", ssid=%s", self->ssid);
|
||||
mp_printf(print, ", ssid=%s", self->ssid);
|
||||
}
|
||||
print(env, ", security=%u>", self->security);
|
||||
mp_printf(print, ", security=%u>", self->security);
|
||||
}
|
||||
|
||||
/// \method connect(ssid, security=OPEN, key=None, bssid=None)
|
||||
@@ -756,10 +778,8 @@ STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
if (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION)) {
|
||||
if (0 == sl_WlanDisconnect()) {
|
||||
while (IS_CONNECTED(wlan_obj.status)) {
|
||||
#ifndef SL_PLATFORM_MULTI_THREADED
|
||||
_SlTaskEntry();
|
||||
#endif
|
||||
HAL_Delay (5);
|
||||
wlan_update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -788,10 +808,11 @@ STATIC mp_obj_t wlan_disconnect(mp_obj_t self_in) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_disconnect_obj, wlan_disconnect);
|
||||
|
||||
/// \method is_connected()
|
||||
/// Return true if connected to the AP and an IP address has been assigned. False otherwise.
|
||||
/// Return true if connected to the AP and an IP address has been assigned. Also true if there's any station connected.
|
||||
/// false otherwise.
|
||||
STATIC mp_obj_t wlan_isconnected(mp_obj_t self_in) {
|
||||
if (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION) &&
|
||||
GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED)) {
|
||||
if ((GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION) &&
|
||||
GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED)) || (wlan_obj.staconnected > 0)) {
|
||||
return mp_const_true;
|
||||
}
|
||||
return mp_const_false;
|
||||
@@ -799,37 +820,29 @@ STATIC mp_obj_t wlan_isconnected(mp_obj_t self_in) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_isconnected_obj, wlan_isconnected);
|
||||
|
||||
STATIC mp_obj_t wlan_ifconfig (mp_obj_t self_in) {
|
||||
STATIC const qstr wlan_ifconfig_fields[] = {
|
||||
MP_QSTR_mode, MP_QSTR_ssid,
|
||||
MP_QSTR_mac, MP_QSTR_bssid,
|
||||
MP_QSTR_ip, MP_QSTR_subnet,
|
||||
MP_QSTR_gateway, MP_QSTR_dns
|
||||
};
|
||||
|
||||
unsigned char len = sizeof(SlNetCfgIpV4Args_t);
|
||||
unsigned char dhcpIsOn;
|
||||
SlNetCfgIpV4Args_t ipV4;
|
||||
|
||||
sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO, &dhcpIsOn, &len, (uint8_t *)&ipV4);
|
||||
// shift byte order
|
||||
ipV4.ipV4Mask = ntohl(ipV4.ipV4Mask);
|
||||
|
||||
mp_obj_t ifconfig = mp_obj_new_dict(0);
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("ip", strlen("ip"), false), mod_network_format_ipv4_addr((uint8_t *)&wlan_obj.ip));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("subnet", strlen("subnet"), false), mod_network_format_ipv4_addr((uint8_t *)&ipV4.ipV4Mask));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("gateway", strlen("gateway"), false), mod_network_format_ipv4_addr((uint8_t *)&wlan_obj.gateway));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("dns", strlen("dns"), false), mod_network_format_ipv4_addr((uint8_t *)&wlan_obj.dns));
|
||||
char mac_str[18];
|
||||
mp_uint_t mac_len = snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", wlan_obj.mac[0], wlan_obj.mac[1], wlan_obj.mac[2],
|
||||
wlan_obj.mac[3], wlan_obj.mac[4], wlan_obj.mac[5]);
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("mac", strlen("mac"), false), mp_obj_new_str(mac_str, mac_len, false));
|
||||
char *mode_str;
|
||||
if (wlan_obj.mode == ROLE_STA) {
|
||||
mode_str = "station";
|
||||
}
|
||||
else if (wlan_obj.mode == ROLE_AP) {
|
||||
mode_str = "ap";
|
||||
}
|
||||
else {
|
||||
mode_str = "p2p";
|
||||
}
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("mode", strlen("mode"), false), mp_obj_new_str(mode_str, strlen(mode_str), false));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("ssid", strlen("ssid"), false), mp_obj_new_str((const char *)wlan_obj.ssid, strlen((const char *)wlan_obj.ssid), false));
|
||||
mp_obj_t ifconfig[8];
|
||||
ifconfig[0] = mp_obj_new_int(wlan_obj.mode);
|
||||
ifconfig[1] = mp_obj_new_str((const char *)wlan_obj.ssid, strlen((const char *)wlan_obj.ssid), false);
|
||||
ifconfig[2] = mp_obj_new_bytes((const byte *)wlan_obj.bssid, SL_BSSID_LENGTH);
|
||||
ifconfig[3] = mp_obj_new_bytes((const byte *)wlan_obj.mac, SL_BSSID_LENGTH);
|
||||
ifconfig[4] = netutils_format_ipv4_addr((uint8_t *)&wlan_obj.ip, NETUTILS_LITTLE);
|
||||
ifconfig[5] = netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4Mask, NETUTILS_LITTLE);
|
||||
ifconfig[6] = netutils_format_ipv4_addr((uint8_t *)&wlan_obj.gateway, NETUTILS_LITTLE);
|
||||
ifconfig[7] = netutils_format_ipv4_addr((uint8_t *)&wlan_obj.dns, NETUTILS_LITTLE);
|
||||
|
||||
return ifconfig;
|
||||
return mp_obj_new_attrtuple(wlan_ifconfig_fields, 8, ifconfig);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_ifconfig_obj, wlan_ifconfig);
|
||||
|
||||
@@ -867,38 +880,49 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_urn_obj, 1, 2, wlan_urn);
|
||||
/// \method wlan_netlist()
|
||||
/// Return a list of tuples with all the acces points within range
|
||||
STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
|
||||
STATIC const qstr wlan_scan_info_fields[] = {
|
||||
MP_QSTR_ssid, MP_QSTR_bssid,
|
||||
MP_QSTR_security, MP_QSTR_channel, MP_QSTR_rssi
|
||||
};
|
||||
|
||||
Sl_WlanNetworkEntry_t wlanEntry;
|
||||
uint8_t _index = 0;
|
||||
mp_obj_t nets = NULL;
|
||||
|
||||
// trigger a new newtork scanning
|
||||
// trigger a new network scan
|
||||
uint32_t scanSeconds = MODWLAN_SCAN_PERIOD_S;
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_SCAN , MODWLAN_SL_SCAN_ENABLE, (_u8 *)&scanSeconds, sizeof(scanSeconds)));
|
||||
|
||||
// wait for the scan to be completed
|
||||
// wait for the scan to complete
|
||||
HAL_Delay (MODWLAN_WAIT_FOR_SCAN_MS);
|
||||
|
||||
do {
|
||||
if (sl_WlanGetNetworkList(_index++, 1, &wlanEntry) <= 0) {
|
||||
break;
|
||||
}
|
||||
mp_obj_t tuple[4];
|
||||
|
||||
if (_index == 1) {
|
||||
// initialize the list
|
||||
nets = mp_obj_new_list(0, NULL);
|
||||
}
|
||||
// we must skip any duplicated results
|
||||
else if (!wlan_scan_result_is_unique(nets, wlanEntry.bssid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mp_obj_t tuple[5];
|
||||
tuple[0] = mp_obj_new_str((const char *)wlanEntry.ssid, wlanEntry.ssid_len, false);
|
||||
tuple[1] = mp_obj_new_str((const char *)wlanEntry.bssid, SL_BSSID_LENGTH, false);
|
||||
// 'Normalize' the security type
|
||||
tuple[1] = mp_obj_new_bytes((const byte *)wlanEntry.bssid, SL_BSSID_LENGTH);
|
||||
// 'normalize' the security type
|
||||
if (wlanEntry.sec_type > 2) {
|
||||
wlanEntry.sec_type = 2;
|
||||
}
|
||||
tuple[2] = mp_obj_new_int(wlanEntry.sec_type);
|
||||
tuple[3] = mp_obj_new_int(wlanEntry.rssi);
|
||||
tuple[3] = mp_const_none;
|
||||
tuple[4] = mp_obj_new_int(wlanEntry.rssi);
|
||||
|
||||
if (_index == 1) {
|
||||
// Initialize the set
|
||||
nets = mp_obj_new_set(0, NULL);
|
||||
}
|
||||
// Add the network found to the list if it's unique
|
||||
mp_obj_set_store(nets, mp_obj_new_tuple(4, tuple));
|
||||
// add the network to the list
|
||||
mp_obj_list_append(nets, mp_obj_new_attrtuple(wlan_scan_info_fields, 5, tuple));
|
||||
|
||||
} while (_index < MODWLAN_SL_MAX_NETWORKS);
|
||||
|
||||
@@ -933,6 +957,76 @@ STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_callback_obj, 1, wlan_callback);
|
||||
|
||||
/// \method config_ip(mode, *, ip='192.168.1.1', subnet='255.255.255.0', gateway='192.168.1.1', dns='8.8.8.8')
|
||||
STATIC mp_obj_t wlan_config_ip (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = MODWLAN_IP_MODE_DYNAMIC} },
|
||||
{ MP_QSTR_ip, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_subnet, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_gateway, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_dns, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if (args[0].u_int == MODWLAN_IP_MODE_DYNAMIC) {
|
||||
// only mode must be given
|
||||
if (args[1].u_obj || args[2].u_obj || args[3].u_obj || args[4].u_obj) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
wlan_servers_stop();
|
||||
|
||||
// nothing to do if we are an access point
|
||||
if (wlan_obj.mode != ROLE_AP) {
|
||||
_u8 val = 1;
|
||||
sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, 1, &val);
|
||||
wlan_reenable (wlan_obj.mode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// we need all arguments at this point
|
||||
if (!args[1].u_obj || !args[2].u_obj || !args[3].u_obj || !args[4].u_obj) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
SlNetCfgIpV4Args_t ipV4;
|
||||
netutils_parse_ipv4_addr(args[1].u_obj, (uint8_t *)&ipV4.ipV4, NETUTILS_LITTLE);
|
||||
netutils_parse_ipv4_addr(args[2].u_obj, (uint8_t *)&ipV4.ipV4Mask, NETUTILS_LITTLE);
|
||||
netutils_parse_ipv4_addr(args[3].u_obj, (uint8_t *)&ipV4.ipV4Gateway, NETUTILS_LITTLE);
|
||||
netutils_parse_ipv4_addr(args[4].u_obj, (uint8_t *)&ipV4.ipV4DnsServer, NETUTILS_LITTLE);
|
||||
|
||||
wlan_servers_stop();
|
||||
|
||||
if (wlan_obj.mode == ROLE_AP) {
|
||||
ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4));
|
||||
|
||||
// stop and start again
|
||||
wlan_reenable(wlan_obj.mode);
|
||||
|
||||
SlNetAppDhcpServerBasicOpt_t dhcpParams;
|
||||
dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address
|
||||
dhcpParams.ipv4_addr_start = ipV4.ipV4 + 1; // first IP Address for allocation.
|
||||
dhcpParams.ipv4_addr_last = (ipV4.ipV4 & 0xFFFFFF00) + 254; // last IP Address for allocation.
|
||||
ASSERT_ON_ERROR(sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID)); // stop DHCP server before settings
|
||||
ASSERT_ON_ERROR(sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
|
||||
sizeof(SlNetAppDhcpServerBasicOpt_t), (_u8* )&dhcpParams)); // set parameters
|
||||
ASSERT_ON_ERROR(sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID)); // start DHCP server with new settings
|
||||
}
|
||||
else {
|
||||
ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_STA_P2P_CL_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4));
|
||||
}
|
||||
wlan_reenable (wlan_obj.mode);
|
||||
}
|
||||
|
||||
wlan_servers_start();
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_config_ip_obj, 1, wlan_config_ip);
|
||||
|
||||
STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&wlan_connect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&wlan_scan_obj },
|
||||
@@ -941,6 +1035,7 @@ STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&wlan_ifconfig_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urn), (mp_obj_t)&wlan_urn_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&wlan_callback_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_config_ip), (mp_obj_t)&wlan_config_ip_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OPEN), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_OPEN) },
|
||||
@@ -952,6 +1047,8 @@ STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STA), MP_OBJ_NEW_SMALL_INT(ROLE_STA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AP), MP_OBJ_NEW_SMALL_INT(ROLE_AP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_P2P), MP_OBJ_NEW_SMALL_INT(ROLE_P2P) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_DYNAMIC), MP_OBJ_NEW_SMALL_INT(MODWLAN_IP_MODE_DYNAMIC) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STATIC), MP_OBJ_NEW_SMALL_INT(MODWLAN_IP_MODE_STATIC) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
|
||||
|
||||
@@ -968,10 +1065,10 @@ STATIC int wlan_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uin
|
||||
uint32_t ip;
|
||||
int result = sl_NetAppDnsGetHostByName((_i8 *)name, (_u16)len, (_u32*)&ip, (_u8)family);
|
||||
|
||||
out_ip[0] = ip >> 24;
|
||||
out_ip[1] = ip >> 16;
|
||||
out_ip[2] = ip >> 8;
|
||||
out_ip[3] = ip;
|
||||
out_ip[0] = ip;
|
||||
out_ip[1] = ip >> 8;
|
||||
out_ip[2] = ip >> 16;
|
||||
out_ip[3] = ip >> 24;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -53,10 +53,11 @@ extern _SlLockObj_t wlan_LockObj;
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
extern void wlan_init0 (void);
|
||||
extern void wlan_pre_init (void);
|
||||
extern modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec,
|
||||
const char *key, uint8_t key_len, uint8_t channel);
|
||||
extern void wlan_first_start (void);
|
||||
extern void wlan_update(void);
|
||||
extern void wlan_stop (uint32_t timeout);
|
||||
extern void wlan_start (void);
|
||||
extern void wlan_get_mac (uint8_t *macAddress);
|
||||
|
||||
@@ -100,9 +100,9 @@ STATIC pyb_adc_obj_t pyb_adc_obj[PYB_ADC_NUM_CHANNELS];
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings : adc object */
|
||||
|
||||
STATIC void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
print(env, "<ADC, channel=%u>", self->num);
|
||||
mp_printf(print, "<ADC, channel=%u>", self->num);
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(channel)
|
||||
|
||||
@@ -294,13 +294,13 @@ STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
STATIC void pyb_i2c_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<I2C0, I2C.MASTER, baudrate=%u>)", self->baudrate);
|
||||
mp_printf(print, "<I2C0, I2C.MASTER, baudrate=%u>)", self->baudrate);
|
||||
}
|
||||
else {
|
||||
print(env, "<I2C0>");
|
||||
mp_print_str(print, "<I2C0>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,29 +61,7 @@
|
||||
///
|
||||
/// Usage Model:
|
||||
///
|
||||
/// All CPU Pins are predefined as pyb.Pin.cpu.Name
|
||||
///
|
||||
/// GPIO9_pin = pyb.Pin.cpu.GPIO9
|
||||
///
|
||||
/// g = pyb.Pin(pyb.Pin.cpu.GPIO9, 0, pyb.Pin.IN)
|
||||
///
|
||||
/// CPU pins which correspond to the board pins are available
|
||||
/// as `pyb.cpu.Name`.
|
||||
///
|
||||
/// You can also use strings:
|
||||
///
|
||||
/// g = pyb.Pin('GPIO9', 0)
|
||||
///
|
||||
/// And finally, you can also pass a pin number directly:
|
||||
///
|
||||
/// g = pyb.Pin(64, 0)
|
||||
///
|
||||
/// To summarise, the following order determines how things get mapped into
|
||||
/// an ordinal pin number:
|
||||
///
|
||||
/// 1. Directly specify a Pin object
|
||||
/// 2. Supply a string which matches a CPU pin name
|
||||
/// 3. Provide a pin number
|
||||
/// g = pyb.Pin('GPIO9', af=0, mode=pyb.Pin.IN, type=pyb.Pin.STD, strength=pyb.Pin.S2MA)
|
||||
///
|
||||
/// \Interrupts:
|
||||
//// You can also configure the Pin to generate interrupts
|
||||
@@ -91,7 +69,7 @@
|
||||
/// Example callback:
|
||||
///
|
||||
/// def pincb(pin):
|
||||
/// print(pin.pin())
|
||||
/// print(pin.get_config().name)
|
||||
///
|
||||
/// extint = pyb.Pin('GPIO10', 0, pyb.Pin.INT_RISING, pyb.GPIO.STD_PD, pyb.S2MA)
|
||||
/// extint.callback (intmode=pyb.Pin.INT_RISING, handler=pincb)
|
||||
@@ -166,28 +144,18 @@ void pin_init0(void) {
|
||||
pin_obj_t *pin_find(mp_obj_t user_obj) {
|
||||
pin_obj_t *pin_obj;
|
||||
|
||||
// If a pin was provided, then use it
|
||||
// if a pin was provided, use it
|
||||
if (MP_OBJ_IS_TYPE(user_obj, &pin_type)) {
|
||||
pin_obj = user_obj;
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
// See if the pin name matches a cpu pin
|
||||
// otherwise see if the pin name matches a cpu pin
|
||||
pin_obj = pin_find_named_pin(&pin_cpu_pins_locals_dict, user_obj);
|
||||
if (pin_obj) {
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
// See if the pin number matches a cpu pin
|
||||
mp_int_t pin_num;
|
||||
if (mp_obj_get_int_maybe(user_obj, &pin_num)) {
|
||||
// The Pins dictionary has pin indexes, so we must substract one from the value passed
|
||||
pin_obj = pin_find_pin(&pin_cpu_pins_locals_dict, (pin_num - 1));
|
||||
if (pin_obj) {
|
||||
return pin_obj;
|
||||
}
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
@@ -387,7 +355,7 @@ STATIC const mp_arg_t pin_init_args[] = {
|
||||
{ MP_QSTR_af, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = GPIO_DIR_MODE_OUT} },
|
||||
{ MP_QSTR_type, MP_ARG_INT, {.u_int = PIN_TYPE_STD} },
|
||||
{ MP_QSTR_str, MP_ARG_INT, {.u_int = PIN_STRENGTH_4MA} },
|
||||
{ MP_QSTR_strength, MP_ARG_INT, {.u_int = PIN_STRENGTH_4MA} },
|
||||
};
|
||||
#define pin_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
|
||||
|
||||
@@ -429,25 +397,26 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_
|
||||
|
||||
/// \method print()
|
||||
/// Return a string describing the pin object.
|
||||
STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_obj_t *self = self_in;
|
||||
uint32_t af = MAP_PinModeGet(self->pin_num);
|
||||
uint32_t type = pin_get_type(self);
|
||||
uint32_t strength = pin_get_strenght(self);
|
||||
uint32_t af = self->af;
|
||||
uint32_t type = self->type;
|
||||
uint32_t strength = self->strength;
|
||||
|
||||
// pin name
|
||||
print(env, "<Pin.cpu.%s, af=%u", qstr_str(self->name), af);
|
||||
mp_printf(print, "<Pin.cpu.%q, af=%u", self->name, af);
|
||||
|
||||
// pin mode
|
||||
if (af == PIN_MODE_0) {
|
||||
// IO mode
|
||||
qstr mode_qst;
|
||||
uint32_t mode = pin_get_mode(self);
|
||||
uint32_t mode = self->mode;
|
||||
if (mode == GPIO_DIR_MODE_IN) {
|
||||
mode_qst = MP_QSTR_IN;
|
||||
} else {
|
||||
mode_qst = MP_QSTR_OUT;
|
||||
}
|
||||
print(env, ", mode=Pin.%s", qstr_str(mode_qst)); // safe because mode_qst has no formatting chars
|
||||
mp_printf(print, ", mode=Pin.%q", mode_qst);
|
||||
}
|
||||
|
||||
// pin type
|
||||
@@ -465,9 +434,9 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
|
||||
} else {
|
||||
type_qst = MP_QSTR_OD_PD;
|
||||
}
|
||||
print(env, ", pull=Pin.%s", qstr_str(type_qst));
|
||||
mp_printf(print, ", type=Pin.%q", type_qst);
|
||||
|
||||
// Strength
|
||||
// pin strength
|
||||
qstr str_qst;
|
||||
if (strength == PIN_STRENGTH_2MA) {
|
||||
str_qst = MP_QSTR_S2MA;
|
||||
@@ -476,7 +445,7 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
|
||||
} else {
|
||||
str_qst = MP_QSTR_S6MA;
|
||||
}
|
||||
print(env, ", strength=Pin.%s>", qstr_str(str_qst));
|
||||
mp_printf(print, ", strength=Pin.%q>", str_qst);
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(id, ...)
|
||||
@@ -554,65 +523,25 @@ STATIC mp_obj_t pin_toggle(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_toggle_obj, pin_toggle);
|
||||
|
||||
/// \method name()
|
||||
/// Get the pin name.
|
||||
STATIC mp_obj_t pin_name(mp_obj_t self_in) {
|
||||
/// \method get_config()
|
||||
/// Returns a named tupple with the current configuration of the gpio pin
|
||||
STATIC mp_obj_t pin_get_config(mp_obj_t self_in) {
|
||||
STATIC const qstr pin_config_fields[] = {
|
||||
MP_QSTR_name, MP_QSTR_af, MP_QSTR_mode,
|
||||
MP_QSTR_type, MP_QSTR_strength
|
||||
};
|
||||
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_QSTR(self->name);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_name_obj, pin_name);
|
||||
mp_obj_t pin_config[5];
|
||||
pin_config[0] = MP_OBJ_NEW_QSTR(self->name);
|
||||
pin_config[1] = mp_obj_new_int(self->af);
|
||||
pin_config[2] = mp_obj_new_int(self->mode);
|
||||
pin_config[3] = mp_obj_new_int(self->type);
|
||||
pin_config[4] = mp_obj_new_int(self->strength);
|
||||
|
||||
/// \method port()
|
||||
/// Get the pin port.
|
||||
STATIC mp_obj_t pin_port(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return mp_obj_new_int(self->port);
|
||||
return mp_obj_new_attrtuple(pin_config_fields, 5, pin_config);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_port_obj, pin_port);
|
||||
|
||||
/// \method pin()
|
||||
/// Get the pin number.
|
||||
STATIC mp_obj_t pin_pin(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT(self->pin_num);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_pin_obj, pin_pin);
|
||||
|
||||
/// \method mode()
|
||||
/// Returns the currently configured mode of the gpio pin. The integer returned
|
||||
/// will match one of the allowed constants for the mode argument to the init
|
||||
/// function.
|
||||
STATIC mp_obj_t pin_mode(mp_obj_t self_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get_mode(self_in));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_mode_obj, pin_mode);
|
||||
|
||||
/// \method type()
|
||||
/// Returns the currently configured type of the pin. The integer returned
|
||||
/// will match one of the allowed constants for the type argument to the init
|
||||
/// function.
|
||||
STATIC mp_obj_t pin_type_get(mp_obj_t self_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get_type(self_in));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_type_obj, pin_type_get);
|
||||
|
||||
/// \method strength()
|
||||
/// Returns the currently configured drive strength of the pin. The integer returned
|
||||
/// will match one of the allowed constants for the strength argument to the init
|
||||
/// function.
|
||||
STATIC mp_obj_t pin_strength(mp_obj_t self_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get_strenght(self_in));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_strenght_obj, pin_strength);
|
||||
|
||||
/// \method af()
|
||||
/// Returns the currently configured alternate function of the gpio pin. The integer returned
|
||||
/// will match one of the allowed constants for the af argument to the init function.
|
||||
STATIC mp_obj_t pin_af(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT(MAP_PinModeGet(self->pin_num));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_obj, pin_af);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_get_config_obj, pin_get_config);
|
||||
|
||||
/// \method callback(method, intmode, priority, pwrmode)
|
||||
/// Creates a callback object associated to a pin
|
||||
@@ -750,18 +679,9 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pin_low_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&pin_toggle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mode), (mp_obj_t)&pin_mode_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_type), (mp_obj_t)&pin_type_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_strength), (mp_obj_t)&pin_strenght_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_af), (mp_obj_t)&pin_af_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_config), (mp_obj_t)&pin_get_config_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pin_callback_obj },
|
||||
|
||||
// class attributes
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj_type },
|
||||
|
||||
// class constants
|
||||
/// \constant IN - set the pin to input mode
|
||||
/// \constant OUT - set the pin to output mode
|
||||
|
||||
@@ -25,13 +25,18 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file requires pin_defs_xxx.h (which has port specific enums and
|
||||
// defines, so we include it here. It should never be included directly
|
||||
|
||||
#include MICROPY_PIN_DEFS_PORT_H
|
||||
#ifndef PYBPIN_H_
|
||||
#define PYBPIN_H_
|
||||
|
||||
#define PYBPIN_ANALOG_TYPE 0xFF
|
||||
|
||||
enum {
|
||||
PORT_A0 = GPIOA0_BASE,
|
||||
PORT_A1 = GPIOA1_BASE,
|
||||
PORT_A2 = GPIOA2_BASE,
|
||||
PORT_A3 = GPIOA3_BASE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const mp_obj_base_t base;
|
||||
const qstr name;
|
||||
@@ -67,9 +72,9 @@ void pin_config(pin_obj_t *self, uint af, uint mode, uint type, uint strength);
|
||||
void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority);
|
||||
pin_obj_t *pin_find(mp_obj_t user_obj);
|
||||
pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
|
||||
pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num);
|
||||
pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit);
|
||||
uint32_t pin_get_mode(const pin_obj_t *self);
|
||||
uint32_t pin_get_type(const pin_obj_t *self);
|
||||
uint32_t pin_get_strenght(const pin_obj_t *self);
|
||||
|
||||
#endif // PYBPIN_H_
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modutime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@@ -40,6 +39,7 @@
|
||||
#include "pybrtc.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpcallback.h"
|
||||
#include "timeutils.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class RTC - real time clock
|
||||
@@ -82,7 +82,7 @@ void pybrtc_init(void) {
|
||||
// fresh reset; configure the RTC Calendar
|
||||
// set the date to 1st Jan 2015
|
||||
// set the time to 00:00:00
|
||||
uint32_t seconds = mod_time_seconds_since_2000(2015, 1, 1, 0, 0, 0);
|
||||
uint32_t seconds = timeutils_seconds_since_2000(2015, 1, 1, 0, 0, 0);
|
||||
|
||||
// Mark the RTC in use first
|
||||
MAP_PRCMRTCInUseSet();
|
||||
@@ -111,11 +111,13 @@ STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) {
|
||||
STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
// check the wake from param
|
||||
if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// enable the slow clock interrupt
|
||||
// disable the slow clock interrupt
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
// disable wake from ldps and hibernate
|
||||
pybsleep_configure_timer_wakeup (PYB_PWR_MODE_ACTIVE);
|
||||
// read the interrupt status to clear any pending interrupt
|
||||
(void)MAP_PRCMIntStatus();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -135,7 +137,7 @@ STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
/// `weekday` is 0-6 for Monday through Sunday.
|
||||
///
|
||||
mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
mod_struct_time tm;
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
@@ -143,7 +145,7 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mseconds = RTC_CYCLES_U16MS(mseconds);
|
||||
mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
@@ -170,7 +172,7 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
tm.tm_sec = mp_obj_get_int(items[6]);
|
||||
mseconds = mp_obj_get_int(items[7]);
|
||||
|
||||
seconds = mod_time_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
seconds = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
mseconds = RTC_U16MS_CYCLES(mseconds);
|
||||
MAP_PRCMRTCSet(seconds, mseconds);
|
||||
|
||||
@@ -217,7 +219,7 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
||||
// set the lpds callback
|
||||
pybsleep_set_timer_lpds_callback(_callback);
|
||||
|
||||
// the interrupt priority is ignored since is already set to to highest level by the sleep module
|
||||
// the interrupt priority is ignored since it's already set to to highest level by the sleep module
|
||||
// to make sure that the wakeup callbacks are always called first when resuming from sleep
|
||||
|
||||
// enable the interrupt (the object is not relevant here, the function already knows it)
|
||||
|
||||
@@ -73,7 +73,7 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pybsd_enable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybsd_init0 (void) {
|
||||
@@ -86,7 +86,7 @@ void pybsd_deinit (void) {
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
/// Initalizes the sd card driver
|
||||
STATIC void pybsd_init (pybsd_obj_t *self) {
|
||||
@@ -148,13 +148,13 @@ STATIC mp_obj_t pybsd_enable (mp_obj_t self_in) {
|
||||
// do the init first
|
||||
pybsd_init (self);
|
||||
|
||||
// try to mount the sd card on /SD
|
||||
if (FR_OK != f_mount(self->fatfs, "/SD", 1)) {
|
||||
// try to mount the sd card on /sd
|
||||
if (FR_OK != f_mount(self->fatfs, "/sd", 1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD_slash_LIB));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)&pybsd_obj, (WakeUpCB_t)pybsd_init);
|
||||
@@ -172,10 +172,10 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) {
|
||||
if (self->enabled) {
|
||||
self->enabled = false;
|
||||
// unmount the sd card
|
||||
f_mount (NULL, "/SD", 1);
|
||||
f_mount (NULL, "/sd", 1);
|
||||
// remove sd paths from mp_sys_path
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD_slash_LIB));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
|
||||
|
||||
// disable the peripheral
|
||||
MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
@@ -186,8 +186,8 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) {
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove (self);
|
||||
|
||||
// change the drive in case it was /SD
|
||||
f_chdrive("/SFLASH");
|
||||
// change the drive in case it was /sd
|
||||
f_chdrive("/flash");
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -124,6 +123,7 @@ STATIC nvic_reg_store_t *nvic_reg_store;
|
||||
STATIC pybsleep_data_t pybsleep_data = {NULL, NULL, NULL, 0};
|
||||
volatile arm_cm4_core_regs_t vault_arm_registers;
|
||||
STATIC pybsleep_reset_cause_t pybsleep_reset_cause = PYB_SLP_PWRON_RESET;
|
||||
STATIC pybsleep_reset_cause_t pybsleep_wake_reason = PYB_SLP_WAKED_PWRON;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
@@ -180,6 +180,17 @@ void pybsleep_init0 (void) {
|
||||
}
|
||||
else {
|
||||
pybsleep_reset_cause = PYB_SLP_HIB_RESET;
|
||||
// set the correct wake reason
|
||||
switch (MAP_PRCMHibernateWakeupCauseGet()) {
|
||||
case PRCM_HIB_WAKEUP_CAUSE_SLOW_CLOCK:
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_RTC;
|
||||
break;
|
||||
case PRCM_HIB_WAKEUP_CAUSE_GPIO:
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_GPIO;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -411,15 +422,18 @@ STATIC void PRCMInterruptHandler (void) {
|
||||
switch (MAP_PRCMLPDSWakeupCauseGet()) {
|
||||
case PRCM_LPDS_HOST_IRQ:
|
||||
mpcallback_handler(pybsleep_data.wlan_lpds_wake_cb);
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_WLAN;
|
||||
break;
|
||||
case PRCM_LPDS_GPIO:
|
||||
mpcallback_handler(pybsleep_data.gpio_lpds_wake_cb);
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_GPIO;
|
||||
break;
|
||||
case PRCM_LPDS_TIMER:
|
||||
// disable the timer as a wake-up source
|
||||
pybsleep_data.timer_wake_pwrmode &= ~PYB_PWR_MODE_LPDS;
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
|
||||
mpcallback_handler(pybsleep_data.timer_lpds_wake_cb);
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_RTC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -631,7 +645,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_reset_cause_obj, pyb_sleep_reset_caus
|
||||
/// \function wake_reason()
|
||||
/// Returns the wake up reson from ldps or hibernate
|
||||
STATIC mp_obj_t pyb_sleep_wake_reason (mp_obj_t self_in) {
|
||||
return mp_const_none;
|
||||
return MP_OBJ_NEW_SMALL_INT(pybsleep_wake_reason);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_wake_reason_obj, pyb_sleep_wake_reason);
|
||||
|
||||
@@ -647,13 +661,13 @@ STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SUSPENDED), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HIBERNATING), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PWR_ON_RESET), 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) },
|
||||
{ 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_HIB_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_SOFT_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_PIN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_GPIO) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) },
|
||||
};
|
||||
|
||||
@@ -661,7 +675,7 @@ STATIC MP_DEFINE_CONST_DICT(pybsleep_locals_dict, pybsleep_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pybsleep_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_sleep,
|
||||
.name = MP_QSTR_Sleep,
|
||||
.locals_dict = (mp_obj_t)&pybsleep_locals_dict,
|
||||
};
|
||||
|
||||
|
||||
@@ -42,19 +42,17 @@ typedef enum {
|
||||
PYB_SLP_HARD_RESET,
|
||||
PYB_SLP_WDT_RESET,
|
||||
PYB_SLP_HIB_RESET,
|
||||
PYB_SLP_SOFT_RESET,
|
||||
|
||||
PYB_SLP_SOFT_RESET
|
||||
} pybsleep_reset_cause_t;
|
||||
|
||||
typedef enum {
|
||||
PYB_SLP_WAKED_PWRON = 0,
|
||||
PYB_SLP_WAKED_BY_WLAN,
|
||||
PYB_SLP_WAKED_BY_PIN,
|
||||
PYB_SLP_WAKED_BY_GPIO,
|
||||
PYB_SLP_WAKED_BY_RTC
|
||||
|
||||
} pybsleep_wake_reason_t;
|
||||
|
||||
typedef void (*WakeUpCB_t)(const mp_obj_t self);
|
||||
typedef void (*DeinitCB_t)(const mp_obj_t self);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED VARIABLES
|
||||
|
||||
@@ -163,15 +163,15 @@ STATIC void pybspi_transfer (pyb_spi_obj_t *self, const char *txdata, char *rxda
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
/******************************************************************************/
|
||||
STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_spi_obj_t *self = self_in;
|
||||
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<SPI0, SPI.MASTER, baudrate=%u, config=%u, submode=%u, bits=%u>",
|
||||
mp_printf(print, "<SPI0, SPI.MASTER, baudrate=%u, config=%u, submode=%u, bits=%u>",
|
||||
self->baudrate, self->config, self->submode, (self->wlen * 8));
|
||||
}
|
||||
else {
|
||||
print(env, "<SPI0>");
|
||||
mp_print_str(print, "<SPI0>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -312,37 +312,37 @@ STATIC void uart_callback_disable (mp_obj_t self_in) {
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<UART%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
|
||||
mp_printf(print, "<UART%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
|
||||
switch (self->config & UART_CONFIG_WLEN_MASK) {
|
||||
case UART_CONFIG_WLEN_5:
|
||||
print(env, "5");
|
||||
mp_print_str(print, "5");
|
||||
break;
|
||||
case UART_CONFIG_WLEN_6:
|
||||
print(env, "6");
|
||||
mp_print_str(print, "6");
|
||||
break;
|
||||
case UART_CONFIG_WLEN_7:
|
||||
print(env, "7");
|
||||
mp_print_str(print, "7");
|
||||
break;
|
||||
case UART_CONFIG_WLEN_8:
|
||||
print(env, "8");
|
||||
mp_print_str(print, "8");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_NONE) {
|
||||
print(env, ", parity=None");
|
||||
mp_print_str(print, ", parity=None");
|
||||
} else {
|
||||
print(env, ", parity=%u", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? 0 : 1);
|
||||
mp_printf(print, ", parity=%u", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? 0 : 1);
|
||||
}
|
||||
print(env, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u>",
|
||||
mp_printf(print, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u>",
|
||||
(self->config & UART_CONFIG_STOP_MASK) == UART_CONFIG_STOP_ONE ? 1 : 2,
|
||||
self->timeout, self->timeout_char, self->read_buf_len);
|
||||
}
|
||||
else {
|
||||
print(env, "<UART%u>", self->uart_id);
|
||||
mp_printf(print, "<UART%u>", self->uart_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define MICROPY_COMP_MODULE_CONST (1)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_FINALISER (1)
|
||||
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
|
||||
#define MICROPY_STACK_CHECK (0)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||
@@ -47,6 +48,7 @@
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
#define MICROPY_OPT_COMPUTED_GOTO (0)
|
||||
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
|
||||
#define MICROPY_CPYTHON_COMPAT (0)
|
||||
|
||||
/* Enable FatFS LFNs
|
||||
0: Disable LFN feature.
|
||||
@@ -54,21 +56,26 @@
|
||||
2: Enable LFN with dynamic working buffer on the STACK.
|
||||
3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
*/
|
||||
#define MICROPY_ENABLE_LFN (0)
|
||||
#define MICROPY_LFN_CODE_PAGE (1)
|
||||
#define MICROPY_ENABLE_LFN (2)
|
||||
#define MICROPY_LFN_CODE_PAGE (437) // 1=SFN/ANSI 437=LFN/U.S.(OEM)
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (0)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (0)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (0)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||
#define MICROPY_PY_BUILTINS_EXECFILE (1)
|
||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
|
||||
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (0)
|
||||
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0)
|
||||
#define MICROPY_PY_SYS_MAXSIZE (0)
|
||||
#define MICROPY_PY_SYS_EXIT (1)
|
||||
#define MICROPY_PY_SYS_STDFILES (1)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (1)
|
||||
#define MICROPY_PY_IO_FILEIO (1)
|
||||
#define MICROPY_PY_UBINASCII (1)
|
||||
#define MICROPY_PY_UCTYPES (1)
|
||||
#define MICROPY_PY_UZLIB (0)
|
||||
#define MICROPY_PY_UJSON (1)
|
||||
@@ -90,6 +97,7 @@ extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
|
||||
// extra built in modules to add to the list of known ones
|
||||
extern const struct _mp_obj_module_t pyb_module;
|
||||
extern const struct _mp_obj_module_t mp_module_ubinascii;
|
||||
extern const struct _mp_obj_module_t mp_module_ure;
|
||||
extern const struct _mp_obj_module_t mp_module_ujson;
|
||||
extern const struct _mp_obj_module_t mp_module_uheapq;
|
||||
@@ -101,14 +109,22 @@ extern const struct _mp_obj_module_t mp_module_network;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&mp_module_uos }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mp_module_utime }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&mp_module_uselect }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_usocket }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&mp_module_uos }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_utime), (mp_obj_t)&mp_module_utime }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uselect), (mp_obj_t)&mp_module_uselect }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_usocket }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_re), (mp_obj_t)&mp_module_ure }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_json), (mp_obj_t)&mp_module_ujson }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_heapq), (mp_obj_t)&mp_module_uheapq }, \
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_binascii), (mp_obj_t)&mp_module_ubinascii }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_re), (mp_obj_t)&mp_module_ure }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_json), (mp_obj_t)&mp_module_ujson }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_heapq), (mp_obj_t)&mp_module_uheapq }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&mp_module_uos }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mp_module_utime }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&mp_module_uselect }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_usocket }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_ustruct }, \
|
||||
|
||||
// extra constants
|
||||
#define MICROPY_PORT_CONSTANTS \
|
||||
@@ -128,6 +144,7 @@ extern const struct _mp_obj_module_t mp_module_network;
|
||||
// type definitions for the specific machine
|
||||
#define BYTES_PER_WORD (4)
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
||||
#define MP_SSIZE_MAX (0x7FFFFFFF)
|
||||
|
||||
#define UINT_FMT "%u"
|
||||
#define INT_FMT "%d"
|
||||
@@ -138,6 +155,9 @@ 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;
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len);
|
||||
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
|
||||
|
||||
#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
|
||||
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
|
||||
|
||||
@@ -160,8 +180,13 @@ typedef long mp_off_t;
|
||||
#include "mpconfigboard.h"
|
||||
|
||||
#define MICROPY_HAL_H "cc3200_hal.h"
|
||||
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_cc3200.h"
|
||||
#define MICROPY_PORT_HAS_TELNET (1)
|
||||
#define MICROPY_PORT_HAS_FTP (1)
|
||||
#define MICROPY_PY_SYS_PLATFORM "WiPy"
|
||||
|
||||
#define MICROPY_PORT_WLAN_AP_SSID "wipy-wlan"
|
||||
#define MICROPY_PORT_WLAN_AP_KEY "www.wipy.io"
|
||||
#define MICROPY_PORT_WLAN_AP_SECURITY SL_SEC_TYPE_WPA_WPA2
|
||||
#define MICROPY_PORT_WLAN_AP_CHANNEL 5
|
||||
|
||||
#endif // __INCLUDED_MPCONFIGPORT_H
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -127,7 +126,6 @@ soft_reset:
|
||||
pin_init0();
|
||||
readline_init0();
|
||||
mod_network_init0();
|
||||
wlan_init0();
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
rng_init0();
|
||||
#endif
|
||||
@@ -135,10 +133,11 @@ soft_reset:
|
||||
// we are alive, so let the world know it
|
||||
mperror_enable_heartbeat();
|
||||
|
||||
#ifdef LAUNCHXL
|
||||
// configure the stdio uart pins with the correct alternate functions
|
||||
// param 3 ("mode") is DON'T CARE" for AFs others than GPIO
|
||||
pin_config ((pin_obj_t *)&pin_GPIO1, PIN_MODE_3, 0, PIN_TYPE_STD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GPIO2, PIN_MODE_3, 0, PIN_TYPE_STD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GPIO1, PIN_MODE_3, 0, PIN_TYPE_STD_PU, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GPIO2, PIN_MODE_3, 0, PIN_TYPE_STD_PU, PIN_STRENGTH_2MA);
|
||||
// instantiate the stdio uart
|
||||
mp_obj_t args[2] = {
|
||||
mp_obj_new_int(MICROPY_STDIO_UART),
|
||||
@@ -147,6 +146,9 @@ soft_reset:
|
||||
pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args);
|
||||
// create a callback for the uart, in order to enable the rx interrupts
|
||||
uart_callback_new (pyb_stdio_uart, mp_const_none, MICROPY_STDIO_UART_RX_BUF_SIZE, INT_PRIORITY_LVL_3);
|
||||
#else
|
||||
pyb_stdio_uart = MP_OBJ_NULL;
|
||||
#endif
|
||||
|
||||
pybsleep_reset_cause_t rstcause = pybsleep_get_reset_cause();
|
||||
if (rstcause < PYB_SLP_SOFT_RESET) {
|
||||
@@ -170,16 +172,16 @@ soft_reset:
|
||||
// initialize the serial flash file system
|
||||
mptask_init_sflash_filesystem();
|
||||
|
||||
// append the SFLASH paths to the system path
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SFLASH));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SFLASH_slash_LIB));
|
||||
// append the flash paths to the system path
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
|
||||
|
||||
// reset config variables; they should be set by boot.py
|
||||
MP_STATE_PORT(pyb_config_main) = MP_OBJ_NULL;
|
||||
|
||||
if (!safeboot) {
|
||||
// run boot.py, if it exists
|
||||
const char *boot_py = "BOOT.PY";
|
||||
const char *boot_py = "boot.py";
|
||||
res = f_stat(boot_py, NULL);
|
||||
if (res == FR_OK) {
|
||||
int ret = pyexec_file(boot_py);
|
||||
@@ -204,7 +206,7 @@ soft_reset:
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
|
||||
const char *main_py;
|
||||
if (MP_STATE_PORT(pyb_config_main) == MP_OBJ_NULL) {
|
||||
main_py = "MAIN.PY";
|
||||
main_py = "main.py";
|
||||
} else {
|
||||
main_py = mp_obj_str_get_str(MP_STATE_PORT(pyb_config_main));
|
||||
}
|
||||
@@ -241,7 +243,7 @@ soft_reset_exit:
|
||||
// soft reset
|
||||
pybsleep_signal_soft_reset();
|
||||
|
||||
printf("WiPy: soft reset\n");
|
||||
mp_printf(&mp_plat_print, "PYB: soft reboot\n");
|
||||
|
||||
sflash_disk_flush();
|
||||
|
||||
@@ -270,6 +272,9 @@ STATIC void mptask_pre_init (void) {
|
||||
// this one allocates memory for the nvic vault
|
||||
pybsleep_pre_init();
|
||||
|
||||
// this one allocates mameory for the WLAN semaphore
|
||||
wlan_pre_init();
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
pybsd_init0();
|
||||
#endif
|
||||
@@ -286,38 +291,42 @@ STATIC void mptask_pre_init (void) {
|
||||
}
|
||||
|
||||
STATIC void mptask_init_sflash_filesystem (void) {
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
// Initialise the local flash filesystem.
|
||||
// Create it if needed, and mount in on /sflash.
|
||||
// Create it if needed, and mount in on /flash.
|
||||
// try to mount the flash
|
||||
FRESULT res = f_mount(sflash_fatfs, "/SFLASH", 1);
|
||||
FRESULT res = f_mount(sflash_fatfs, "/flash", 1);
|
||||
if (res == FR_NO_FILESYSTEM) {
|
||||
// no filesystem, so create a fresh one
|
||||
res = f_mkfs("/SFLASH", 1, 0);
|
||||
res = f_mkfs("/flash", 1, 0);
|
||||
if (res == FR_OK) {
|
||||
// success creating fresh LFS
|
||||
} else {
|
||||
__fatal_error("failed to create /SFLASH");
|
||||
__fatal_error("failed to create /flash");
|
||||
}
|
||||
// create empty main.py
|
||||
mptask_create_main_py();
|
||||
} else if (res == FR_OK) {
|
||||
// mount sucessful
|
||||
FILINFO fno;
|
||||
if (FR_OK != f_stat("/SFLASH/MAIN.PY", &fno)) {
|
||||
if (FR_OK != f_stat("/flash/main.py", &fno)) {
|
||||
// create empty main.py
|
||||
mptask_create_main_py();
|
||||
}
|
||||
} else {
|
||||
__fatal_error("failed to create /SFLASH");
|
||||
__fatal_error("failed to create /flash");
|
||||
}
|
||||
|
||||
// The current directory is used as the boot up directory.
|
||||
// It is set to the internal flash filesystem by default.
|
||||
f_chdrive("/SFLASH");
|
||||
f_chdrive("/flash");
|
||||
|
||||
// Make sure we have a /flash/boot.py. Create it if needed.
|
||||
FILINFO fno;
|
||||
res = f_stat("/SFLASH/BOOT.PY", &fno);
|
||||
res = f_stat("/flash/boot.py", &fno);
|
||||
if (res == FR_OK) {
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
// exists as a directory
|
||||
@@ -329,7 +338,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
} else {
|
||||
// doesn't exist, create fresh file
|
||||
FIL fp;
|
||||
f_open(&fp, "/SFLASH/BOOT.PY", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
UINT n;
|
||||
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
|
||||
// TODO check we could write n bytes
|
||||
@@ -338,15 +347,15 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
}
|
||||
|
||||
STATIC void mptask_enter_ap_mode (void) {
|
||||
// Enable simplelink in low power mode
|
||||
wlan_sl_enable (ROLE_AP, SERVERS_DEF_AP_SSID, strlen(SERVERS_DEF_AP_SSID), SERVERS_DEF_AP_SECURITY,
|
||||
SERVERS_DEF_AP_KEY, strlen(SERVERS_DEF_AP_KEY), SERVERS_DEF_AP_CHANNEL);
|
||||
// enable simplelink in low power mode
|
||||
wlan_sl_enable (ROLE_AP, MICROPY_PORT_WLAN_AP_SSID, strlen(MICROPY_PORT_WLAN_AP_SSID), MICROPY_PORT_WLAN_AP_SECURITY,
|
||||
MICROPY_PORT_WLAN_AP_KEY, strlen(MICROPY_PORT_WLAN_AP_KEY), MICROPY_PORT_WLAN_AP_CHANNEL);
|
||||
}
|
||||
|
||||
STATIC void mptask_create_main_py (void) {
|
||||
// create empty main.py
|
||||
FIL fp;
|
||||
f_open(&fp, "/SFLASH/MAIN.PY", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
UINT n;
|
||||
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
|
||||
f_close(&fp);
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// qstrs specific to this port
|
||||
Q(__name__)
|
||||
Q(help)
|
||||
@@ -35,12 +62,15 @@ Q(mkdisk)
|
||||
Q(enable)
|
||||
Q(disable)
|
||||
// Entries for sys.path
|
||||
Q(/SFLASH)
|
||||
Q(/SFLASH/LIB)
|
||||
Q(/SD)
|
||||
Q(/SD/LIB)
|
||||
Q(/flash)
|
||||
Q(/flash/lib)
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
Q(/sd)
|
||||
Q(/sd/lib)
|
||||
#endif
|
||||
|
||||
// for module weak links
|
||||
Q(binascii)
|
||||
Q(re)
|
||||
Q(json)
|
||||
Q(heapq)
|
||||
@@ -48,9 +78,17 @@ Q(heapq)
|
||||
// for os module
|
||||
Q(uos)
|
||||
Q(os)
|
||||
Q(sysname)
|
||||
Q(nodename)
|
||||
Q(release)
|
||||
Q(version)
|
||||
Q(machine)
|
||||
Q(uname)
|
||||
Q(/)
|
||||
Q(SFLASH)
|
||||
Q(SD)
|
||||
Q(flash)
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
Q(sd)
|
||||
#endif
|
||||
Q(chdir)
|
||||
Q(getcwd)
|
||||
Q(listdir)
|
||||
@@ -72,19 +110,13 @@ Q(init)
|
||||
Q(value)
|
||||
Q(low)
|
||||
Q(high)
|
||||
Q(toggle)
|
||||
Q(get_config)
|
||||
Q(name)
|
||||
Q(port)
|
||||
Q(pin)
|
||||
Q(cpu)
|
||||
Q(mode)
|
||||
Q(pull)
|
||||
Q(index)
|
||||
Q(strength)
|
||||
Q(af)
|
||||
Q(intenable)
|
||||
Q(intdisable)
|
||||
Q(intmode)
|
||||
Q(swint)
|
||||
Q(mode)
|
||||
Q(type)
|
||||
Q(strength)
|
||||
Q(IN)
|
||||
Q(OUT)
|
||||
Q(STD)
|
||||
@@ -143,10 +175,12 @@ Q(mem_write)
|
||||
Q(ADC)
|
||||
Q(read)
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// for SD class
|
||||
Q(SD)
|
||||
Q(enable)
|
||||
Q(disable)
|
||||
#endif
|
||||
|
||||
// for RTC class
|
||||
Q(RTC)
|
||||
@@ -190,6 +224,7 @@ Q(AF_INET6)
|
||||
Q(SOCK_STREAM)
|
||||
Q(SOCK_DGRAM)
|
||||
Q(SOCK_RAW)
|
||||
Q(IPPROTO_SEC)
|
||||
Q(IPPROTO_TCP)
|
||||
Q(IPPROTO_UDP)
|
||||
Q(IPPROTO_RAW)
|
||||
@@ -213,8 +248,16 @@ Q(connect)
|
||||
Q(isconnected)
|
||||
Q(disconnect)
|
||||
Q(channel)
|
||||
Q(rssi)
|
||||
Q(ifconfig)
|
||||
Q(urn)
|
||||
Q(mode)
|
||||
Q(config_ip)
|
||||
Q(ip)
|
||||
Q(subnet)
|
||||
Q(gateway)
|
||||
Q(dns)
|
||||
Q(mac)
|
||||
Q(STA)
|
||||
Q(AP)
|
||||
Q(P2P)
|
||||
@@ -224,6 +267,8 @@ Q(WPA_WPA2)
|
||||
Q(WPA_ENT)
|
||||
Q(WPS_PBC)
|
||||
Q(WPS_PIN)
|
||||
Q(DYNAMIC)
|
||||
Q(STATIC)
|
||||
|
||||
// for WDT class
|
||||
Q(WDT)
|
||||
@@ -256,7 +301,7 @@ Q(wake_reason)
|
||||
Q(ACTIVE)
|
||||
Q(SUSPENDED)
|
||||
Q(HIBERNATING)
|
||||
Q(PWR_ON_RESET)
|
||||
Q(POWER_ON)
|
||||
Q(HARD_RESET)
|
||||
Q(WDT_RESET)
|
||||
Q(HIB_RESET)
|
||||
|
||||
@@ -25,16 +25,14 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <std.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/misc.h"
|
||||
#include "simplelink.h"
|
||||
#include "serverstask.h"
|
||||
#include "modwlan.h"
|
||||
#include "simplelink.h"
|
||||
#include "debug.h"
|
||||
#include "mpexception.h"
|
||||
#include "telnet.h"
|
||||
#include "ftp.h"
|
||||
#include "pybwdt.h"
|
||||
@@ -68,8 +66,8 @@ static servers_Data_t servers_data = {.enabled = false, .do_disable = false, .do
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
char *servers_user;
|
||||
char *servers_pass;
|
||||
char servers_user[SERVERS_USER_PASS_LEN_MAX + 1];
|
||||
char servers_pass[SERVERS_USER_PASS_LEN_MAX + 1];
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
@@ -78,8 +76,6 @@ void TASK_Servers (void *pvParameters) {
|
||||
|
||||
bool cycle = false;
|
||||
|
||||
ASSERT ((servers_user = mem_Malloc(SERVERS_USER_LEN_MAX + 1)) != NULL);
|
||||
ASSERT ((servers_pass = mem_Malloc(SERVERS_PASS_LEN_MAX + 1)) != NULL);
|
||||
strcpy (servers_user, SERVERS_DEF_USER);
|
||||
strcpy (servers_pass, SERVERS_DEF_PASS);
|
||||
|
||||
@@ -88,25 +84,7 @@ void TASK_Servers (void *pvParameters) {
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
if (servers_data.enabled) {
|
||||
if (servers_data.do_disable) {
|
||||
// disable network services
|
||||
telnet_disable();
|
||||
ftp_disable();
|
||||
// now clear the flags
|
||||
servers_data.do_disable = false;
|
||||
servers_data.enabled = false;
|
||||
}
|
||||
else {
|
||||
if (cycle) {
|
||||
telnet_run();
|
||||
}
|
||||
else {
|
||||
ftp_run();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (servers_data.do_enable) {
|
||||
if (servers_data.do_enable) {
|
||||
// enable network services
|
||||
telnet_enable();
|
||||
ftp_enable();
|
||||
@@ -114,6 +92,21 @@ void TASK_Servers (void *pvParameters) {
|
||||
servers_data.enabled = true;
|
||||
servers_data.do_enable = false;
|
||||
}
|
||||
else if (servers_data.do_disable) {
|
||||
// disable network services
|
||||
telnet_disable();
|
||||
ftp_disable();
|
||||
// now clear the flags
|
||||
servers_data.do_disable = false;
|
||||
servers_data.enabled = false;
|
||||
}
|
||||
|
||||
if (cycle) {
|
||||
telnet_run();
|
||||
}
|
||||
else {
|
||||
ftp_run();
|
||||
}
|
||||
|
||||
// move to the next cycle
|
||||
cycle = cycle ? false : true;
|
||||
@@ -124,16 +117,16 @@ void TASK_Servers (void *pvParameters) {
|
||||
}
|
||||
|
||||
void servers_start (void) {
|
||||
servers_data.do_disable = false;
|
||||
servers_data.do_enable = true;
|
||||
HAL_Delay (SERVERS_CYCLE_TIME_MS * 5);
|
||||
}
|
||||
|
||||
void servers_stop (void) {
|
||||
servers_data.do_enable = false;
|
||||
servers_data.do_disable = true;
|
||||
do {
|
||||
HAL_Delay (SERVERS_CYCLE_TIME_MS);
|
||||
} while (servers_are_enabled());
|
||||
HAL_Delay (SERVERS_CYCLE_TIME_MS * 5);
|
||||
}
|
||||
|
||||
bool servers_are_enabled (void) {
|
||||
@@ -148,8 +141,8 @@ void servers_close_socket (int16_t *sd) {
|
||||
}
|
||||
|
||||
void servers_set_login (char *user, char *pass) {
|
||||
memcpy(servers_user, user, SERVERS_USER_LEN_MAX);
|
||||
memcpy(servers_pass, pass, SERVERS_PASS_LEN_MAX);
|
||||
memcpy(servers_user, user, SERVERS_USER_PASS_LEN_MAX);
|
||||
memcpy(servers_pass, pass, SERVERS_USER_PASS_LEN_MAX);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@@ -31,18 +31,12 @@
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define SERVERS_PRIORITY 2
|
||||
#define SERVERS_STACK_SIZE 944
|
||||
#define SERVERS_STACK_SIZE 1072
|
||||
|
||||
#define SERVERS_SSID_LEN_MAX 16
|
||||
#define SERVERS_KEY_LEN_MAX 16
|
||||
|
||||
#define SERVERS_USER_LEN_MAX 16
|
||||
#define SERVERS_PASS_LEN_MAX 16
|
||||
|
||||
#define SERVERS_DEF_AP_SSID "micropy-wlan"
|
||||
#define SERVERS_DEF_AP_SECURITY SL_SEC_TYPE_WPA_WPA2
|
||||
#define SERVERS_DEF_AP_KEY "micropython"
|
||||
#define SERVERS_DEF_AP_CHANNEL 6
|
||||
#define SERVERS_USER_PASS_LEN_MAX 16
|
||||
|
||||
#define SERVERS_CYCLE_TIME_MS 5
|
||||
|
||||
@@ -53,8 +47,8 @@
|
||||
/******************************************************************************
|
||||
EXPORTED DATA
|
||||
******************************************************************************/
|
||||
extern char *servers_user;
|
||||
extern char *servers_pass;
|
||||
extern char servers_user[];
|
||||
extern char servers_pass[];
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -36,7 +35,7 @@
|
||||
#include "debug.h"
|
||||
#include "mpexception.h"
|
||||
#include "serverstask.h"
|
||||
#include "genhdr/py-version.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
@@ -129,6 +128,7 @@ static void telnet_send_and_proceed (void *data, _i16 Len, telnet_connected_subs
|
||||
static telnet_result_t telnet_send_non_blocking (void *data, _i16 Len);
|
||||
static telnet_result_t telnet_recv_text_non_blocking (void *buff, _i16 Maxlen, _i16 *rxLen);
|
||||
static void telnet_process (void);
|
||||
static int telnet_process_credential (char *credential, _i16 rxLen);
|
||||
static void telnet_parse_input (uint8_t *str, int16_t *len);
|
||||
static bool telnet_send_with_retries (int16_t sd, const void *pBuf, int16_t len);
|
||||
static void telnet_reset (void);
|
||||
@@ -171,12 +171,14 @@ void telnet_run (void) {
|
||||
telnet_send_and_proceed((void *)telnet_request_user, strlen(telnet_request_user), E_TELNET_STE_SUB_GET_USER);
|
||||
break;
|
||||
case E_TELNET_STE_SUB_GET_USER:
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer, TELNET_RX_BUFFER_SIZE, &rxLen)) {
|
||||
// Skip /r/n
|
||||
if (rxLen < 2 || memcmp(servers_user, (const char *)telnet_data.rxBuffer, MAX((rxLen - 2), strlen(servers_user)))) {
|
||||
telnet_data.credentialsValid = false;
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer + telnet_data.rxWindex,
|
||||
TELNET_RX_BUFFER_SIZE - telnet_data.rxWindex,
|
||||
&rxLen)) {
|
||||
int result;
|
||||
if ((result = telnet_process_credential (servers_user, rxLen))) {
|
||||
telnet_data.credentialsValid = result > 0 ? true : false;
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_REQ_PASSWORD;
|
||||
}
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_REQ_PASSWORD;
|
||||
}
|
||||
break;
|
||||
case E_TELNET_STE_SUB_REQ_PASSWORD:
|
||||
@@ -188,16 +190,17 @@ void telnet_run (void) {
|
||||
telnet_send_and_proceed((void *)telnet_options_pass, sizeof(telnet_options_pass), E_TELNET_STE_SUB_GET_PASSWORD);
|
||||
break;
|
||||
case E_TELNET_STE_SUB_GET_PASSWORD:
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer, TELNET_RX_BUFFER_SIZE, &rxLen)) {
|
||||
// skip /r/n
|
||||
if (rxLen < 2 || memcmp(servers_pass, (const char *)telnet_data.rxBuffer, MAX((rxLen - 2), strlen(servers_pass)))) {
|
||||
telnet_data.credentialsValid = false;
|
||||
}
|
||||
if (telnet_data.credentialsValid) {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_SND_REPL_OPTIONS;
|
||||
}
|
||||
else {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_INVALID_LOGGIN;
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer + telnet_data.rxWindex,
|
||||
TELNET_RX_BUFFER_SIZE - telnet_data.rxWindex,
|
||||
&rxLen)) {
|
||||
int result;
|
||||
if ((result = telnet_process_credential (servers_pass, rxLen))) {
|
||||
if ((telnet_data.credentialsValid = telnet_data.credentialsValid && (result > 0 ? true : false))) {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_SND_REPL_OPTIONS;
|
||||
}
|
||||
else {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_INVALID_LOGGIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -325,7 +328,7 @@ static bool telnet_create_socket (void) {
|
||||
|
||||
// Bind the socket to a port number
|
||||
sServerAddress.sin_family = AF_INET;
|
||||
sServerAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
sServerAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
sServerAddress.sin_port = htons(TELNET_PORT);
|
||||
|
||||
ASSERT (sl_Bind(telnet_data.sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress)) == SL_SOC_OK);
|
||||
@@ -427,6 +430,26 @@ static void telnet_process (void) {
|
||||
}
|
||||
}
|
||||
|
||||
static int telnet_process_credential (char *credential, _i16 rxLen) {
|
||||
telnet_data.rxWindex += rxLen;
|
||||
if (telnet_data.rxWindex >= SERVERS_USER_PASS_LEN_MAX) {
|
||||
telnet_data.rxWindex = SERVERS_USER_PASS_LEN_MAX;
|
||||
}
|
||||
|
||||
uint8_t *p = telnet_data.rxBuffer + SERVERS_USER_PASS_LEN_MAX;
|
||||
// if a '\r' is found, or the length exceeds the max username length
|
||||
if ((p = memchr(telnet_data.rxBuffer, '\r', telnet_data.rxWindex)) || (telnet_data.rxWindex >= SERVERS_USER_PASS_LEN_MAX)) {
|
||||
uint8_t len = p - telnet_data.rxBuffer;
|
||||
|
||||
telnet_data.rxWindex = 0;
|
||||
if ((len > 0) && (memcmp(credential, telnet_data.rxBuffer, MAX(len, strlen(credential))) == 0)) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void telnet_parse_input (uint8_t *str, int16_t *len) {
|
||||
int16_t b_len = *len;
|
||||
uint8_t *b_str = str;
|
||||
@@ -444,8 +467,9 @@ static void telnet_parse_input (uint8_t *str, int16_t *len) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
_str += 3;
|
||||
*len -= 3;
|
||||
// in case we have received an incomplete telnet option, unlikely, but possible
|
||||
_str += MIN(3, *len);
|
||||
*len -= MIN(3, *len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "std.h"
|
||||
#include "fifo.h"
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "std.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "inc/hw_types.h"
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <std.h>
|
||||
#include "osi.h"
|
||||
#include "fifo.h"
|
||||
#include "socketfifo.h"
|
||||
|
||||
@@ -24,21 +24,13 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is needed because in some cases we can't include stdio.h,
|
||||
// because the CC3100 socket driver has name clashes with it.
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
|
||||
size_t strlen(const char *str);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strcat(char *dest, const char *src);
|
||||
char *strchr(const char *s, int c);
|
||||
char *strstr(const char *haystack, const char *needle);
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
int snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
|
||||
// Convenience function, defined in main.c.
|
||||
void stoupper (char *str);
|
||||
|
||||
@@ -1,41 +1,32 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// This file contains pin definitions that are specific to the cc3200 port.
|
||||
// This file should only ever be #included by pybgpio.h and not directly.
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Define types
|
||||
//*****************************************************************************
|
||||
|
||||
enum {
|
||||
PORT_A0 = GPIOA0_BASE,
|
||||
PORT_A1 = GPIOA1_BASE,
|
||||
PORT_A2 = GPIOA2_BASE,
|
||||
PORT_A3 = GPIOA3_BASE
|
||||
};
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* 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 VERSION_H_
|
||||
#define VERSION_H_
|
||||
|
||||
#define WIPY_SW_VERSION_NUMBER "0.9.1"
|
||||
|
||||
#endif /* VERSION_H_ */
|
||||
@@ -60,7 +60,7 @@ copyright = '2014, Damien P. George'
|
||||
# The short X.Y version.
|
||||
version = '1.4'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.4'
|
||||
release = '1.4.3'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
Micro Python libraries
|
||||
======================
|
||||
|
||||
Functionality specific to the Micro Python implementation is available in
|
||||
the following library.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
micropython.rst
|
||||
|
||||
Python standard libraries
|
||||
-------------------------
|
||||
|
||||
|
||||
37
docs/library/micropython.rst
Normal file
37
docs/library/micropython.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
:mod:`micropython` -- access and control Micro Python internals
|
||||
===============================================================
|
||||
|
||||
.. module:: micropython
|
||||
:synopsis: access and control Micro Python internals
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: mem_info([verbose])
|
||||
|
||||
Print information about currently used memory. If the ``verbose`` argument
|
||||
is given then extra information is printed.
|
||||
|
||||
The information that is printed is implementation dependent, but currently
|
||||
includes the amount of stack and heap used. In verbose mode it prints out
|
||||
the entire heap indicating which blocks are used and which are free.
|
||||
|
||||
.. function:: qstr_info([verbose])
|
||||
|
||||
Print information about currently interned strings. If the ``verbose``
|
||||
argument is given then extra information is printed.
|
||||
|
||||
The information that is printed is implementation dependent, but currently
|
||||
includes the number of interned strings and the amount of RAM they use. In
|
||||
verbose mode it prints out the names of all RAM-interned strings.
|
||||
|
||||
.. function:: alloc_emergency_exception_buf(size)
|
||||
|
||||
Allocate ``size`` bytes of RAM for the emergency exception buffer (a good
|
||||
size is around 100 bytes). The buffer is used to create exceptions in cases
|
||||
when normal RAM allocation would fail (eg within an interrupt handler) and
|
||||
therefore give useful traceback information in these situations.
|
||||
|
||||
A good way to use this function is to put it at the start of your main script
|
||||
(eg boot.py or main.py) and then the emergency exception buffer will be active
|
||||
for all the code following it.
|
||||
@@ -46,6 +46,10 @@ Functions
|
||||
|
||||
Remove a directory.
|
||||
|
||||
.. function:: rename(old_path, new_path)
|
||||
|
||||
Rename a file.
|
||||
|
||||
.. function:: stat(path)
|
||||
|
||||
Get the status of a file or directory.
|
||||
|
||||
@@ -82,7 +82,7 @@ Methods
|
||||
|
||||
Turn off the CAN bus.
|
||||
|
||||
.. method:: can.setfilter(bank, mode, fifo, params)
|
||||
.. method:: can.setfilter(bank, mode, fifo, params, \*, rtr)
|
||||
|
||||
Configure a filter bank:
|
||||
|
||||
@@ -107,6 +107,23 @@ Methods
|
||||
|CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.|
|
||||
+-----------+---------------------------------------------------------+
|
||||
|
||||
- ``rtr`` is an array of booleans that states if a filter should accept a
|
||||
remote transmission request message. If this argument is not given
|
||||
then it defaults to False for all entries. The length of the array
|
||||
depends on the ``mode`` argument.
|
||||
|
||||
+-----------+----------------------+
|
||||
|``mode`` |length of rtr array |
|
||||
+===========+======================+
|
||||
|CAN.LIST16 |4 |
|
||||
+-----------+----------------------+
|
||||
|CAN.LIST32 |2 |
|
||||
+-----------+----------------------+
|
||||
|CAN.MASK16 |2 |
|
||||
+-----------+----------------------+
|
||||
|CAN.MASK32 |1 |
|
||||
+-----------+----------------------+
|
||||
|
||||
.. method:: can.clearfilter(bank)
|
||||
|
||||
Clear and disables a filter bank:
|
||||
@@ -124,15 +141,30 @@ Methods
|
||||
- ``fifo`` is an integer, which is the FIFO to receive on
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the receive.
|
||||
|
||||
Return value: buffer of data bytes.
|
||||
Return value: A tuple containing four values.
|
||||
|
||||
.. method:: can.send(send, addr, \*, timeout=5000)
|
||||
- The id of the message.
|
||||
- A boolean that indicates if the message is an RTR message.
|
||||
- The FMI (Filter Match Index) value.
|
||||
- An array containing the data.
|
||||
|
||||
.. method:: can.send(data, id, \*, timeout=0, rtr=False)
|
||||
|
||||
Send a message on the bus:
|
||||
|
||||
- ``send`` is the data to send (an integer to send, or a buffer object).
|
||||
- ``addr`` is the address to send to
|
||||
- ``data`` is the data to send (an integer to send, or a buffer object).
|
||||
- ``id`` is the id of the message to be sent.
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the send.
|
||||
- ``rtr`` is a boolean that specifies if the message shall be sent as
|
||||
a remote transmission request. If ``rtr`` is True then only the length
|
||||
of ``data`` is used to fill in the DLC slot of the frame; the actual
|
||||
bytes in ``data`` are unused.
|
||||
|
||||
If timeout is 0 the message is placed in a buffer in one of three hardware
|
||||
buffers and the method returns immediately. If all three buffers are in use
|
||||
an exception is thrown. If timeout is not 0, the method waits until the
|
||||
message is transmitted. If the message can't be transmitted within the
|
||||
specified time an exception is thrown.
|
||||
|
||||
Return value: ``None``.
|
||||
|
||||
|
||||
@@ -38,6 +38,17 @@ Methods
|
||||
|
||||
``subseconds`` counts down from 255 to 0
|
||||
|
||||
.. method:: rtc.wakeup(timeout, callback=None)
|
||||
|
||||
Set the RTC wakeup timer to trigger repeatedly at every ``timeout``
|
||||
milliseconds. This trigger can wake the pyboard from both the sleep
|
||||
states: :meth:`pyb.stop` and :meth:`pyb.standby`.
|
||||
|
||||
If ``timeout`` is ``None`` then the wakeup timer is disabled.
|
||||
|
||||
If ``callback`` is given then it is executed at every trigger of the
|
||||
wakeup timer. ``callback`` must take exactly one argument.
|
||||
|
||||
.. method:: rtc.info()
|
||||
|
||||
Get information about the startup time and reset source.
|
||||
@@ -46,3 +57,19 @@ Methods
|
||||
start up.
|
||||
- Bit 0x10000 is set if a power-on reset occurred.
|
||||
- Bit 0x20000 is set if an external reset occurred
|
||||
|
||||
.. method:: rtc.calibration(cal)
|
||||
|
||||
Get or set RTC calibration.
|
||||
|
||||
With no arguments, ``calibration()`` returns the current calibration
|
||||
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
|
||||
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
|
||||
ppm; likewise the RTC clock it slowed by negative values. The
|
||||
usable calibration range is:
|
||||
(-511 * 0.954) ~= -487.5 ppm up to (512 * 0.954) ~= 488.5 ppm
|
||||
|
||||
@@ -18,6 +18,13 @@ Example usage to toggle an LED at a fixed frequency::
|
||||
tim.init(freq=2) # trigger at 2Hz
|
||||
tim.callback(lambda t:pyb.LED(1).toggle())
|
||||
|
||||
Example using named function for the callback::
|
||||
|
||||
def tick(timer): # we will receive the timer object when being called
|
||||
print(timer.counter()) # show current timer's counter value
|
||||
tim = pyb.Timer(4, freq=1) # create a timer object using timer 4 - trigger at 1Hz
|
||||
tim.callback(tick) # set the callback to our tick function
|
||||
|
||||
Further examples::
|
||||
|
||||
tim = pyb.Timer(4, freq=100) # freq in Hz
|
||||
@@ -32,6 +39,10 @@ Further examples::
|
||||
the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing.
|
||||
It is recommended to use the other timers in your programs.
|
||||
|
||||
*Note:* Memory can't be allocated during a callback (an interrupt) and so
|
||||
exceptions raised within a callback don't give much information. See
|
||||
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
|
||||
limitation.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
@@ -36,15 +36,49 @@ Methods
|
||||
|
||||
.. method:: usb_vcp.close()
|
||||
|
||||
This method does nothing. It exists so the USB_VCP object can act as
|
||||
a file.
|
||||
|
||||
.. method:: usb_vcp.read([nbytes])
|
||||
|
||||
Read at most ``nbytes`` from the serial device and return them as a
|
||||
bytes object. If ``nbytes`` is not specified then the method acts as
|
||||
``readall()``.
|
||||
|
||||
.. method:: usb_vcp.readall()
|
||||
|
||||
Read all available bytes from the serial device and return them as
|
||||
a bytes object.
|
||||
|
||||
.. method:: usb_vcp.readinto(buf, [maxlen])
|
||||
|
||||
Read bytes from the serial device and store them into ``buf``, which
|
||||
should be a buffer-like object. At most ``len(buf)`` bytes are read.
|
||||
If ``maxlen`` is given and then at most ``min(maxlen, len(buf))`` bytes
|
||||
are read.
|
||||
|
||||
Returns the number of bytes read and stored into ``buf``.
|
||||
|
||||
.. method:: usb_vcp.readline()
|
||||
|
||||
Read a whole line from the serial device.
|
||||
|
||||
Returns a bytes object containing the data, including the trailing
|
||||
newline character.
|
||||
|
||||
.. method:: usb_vcp.readlines()
|
||||
|
||||
Read as much data as possible from the serial device, breaking it into
|
||||
lines.
|
||||
|
||||
Returns a list of bytes objects, each object being one of the lines.
|
||||
Each line will include the newline character.
|
||||
|
||||
.. method:: usb_vcp.write(buf)
|
||||
|
||||
Write the bytes from ``buf`` to the serial device.
|
||||
|
||||
Returns the number of bytes written.
|
||||
|
||||
.. method:: usb_vcp.recv(data, \*, timeout=5000)
|
||||
|
||||
@@ -65,6 +99,3 @@ Methods
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the send.
|
||||
|
||||
Return value: number of bytes sent.
|
||||
|
||||
.. method:: usb_vcp.write(buf)
|
||||
|
||||
|
||||
@@ -133,14 +133,33 @@ Power related functions
|
||||
|
||||
.. function:: wfi()
|
||||
|
||||
Wait for an interrupt.
|
||||
This executies a ``wfi`` instruction which reduces power consumption
|
||||
of the MCU until an interrupt occurs, at which point execution continues.
|
||||
Wait for an internal or external interrupt.
|
||||
|
||||
This executes a ``wfi`` instruction which reduces power consumption
|
||||
of the MCU until any interrupt occurs (be it internal or external),
|
||||
at which point execution continues. Note that the system-tick interrupt
|
||||
occurs once every millisecond (1000Hz) so this function will block for
|
||||
at most 1ms.
|
||||
|
||||
.. function:: stop()
|
||||
|
||||
Put the pyboard in a "sleeping" state.
|
||||
|
||||
This reduces power consumption to less than 500 uA. To wake from this
|
||||
sleep state requires an external interrupt or a real-time-clock event.
|
||||
Upon waking execution continues where it left off.
|
||||
|
||||
See :meth:`rtc.wakeup` to configure a real-time-clock wakeup event.
|
||||
|
||||
.. function:: standby()
|
||||
|
||||
Put the pyboard into a "deep sleep" state.
|
||||
|
||||
.. function:: stop()
|
||||
This reduces power consumption to less than 50 uA. To wake from this
|
||||
sleep state requires an external interrupt or a real-time-clock event.
|
||||
Upon waking the system undergoes a hard reset.
|
||||
|
||||
See :meth:`rtc.wakeup` to configure a real-time-clock wakeup event.
|
||||
|
||||
Miscellaneous functions
|
||||
-----------------------
|
||||
@@ -162,6 +181,13 @@ Miscellaneous functions
|
||||
|
||||
Print out lots of information about the board.
|
||||
|
||||
.. function:: main(filename)
|
||||
|
||||
Set the filename of the main script to run after boot.py is finished. If
|
||||
this function is not called then the default file main.py will be executed.
|
||||
|
||||
It only makes sense to call this function from within boot.py.
|
||||
|
||||
.. function:: mount(device, mountpoint, \*, readonly=False, mkfs=False)
|
||||
|
||||
Mount a block device and make it available as part of the filesystem.
|
||||
|
||||
@@ -98,8 +98,8 @@ Module contents
|
||||
|
||||
.. class:: struct(descriptor, layout_type)
|
||||
|
||||
Create a "foreign data structure" object based on its descriptor (encoded
|
||||
as a dictionary) and layout type.
|
||||
Create a "foreign data structure" class based on its descriptor (encoded
|
||||
as a dictionary) and layout type (see below).
|
||||
|
||||
.. data:: LITTLE_ENDIAN
|
||||
|
||||
@@ -140,6 +140,22 @@ Module contents
|
||||
so it can be both written too, and you will access current value
|
||||
at the given memory address.
|
||||
|
||||
Structure classes and instantiating structure objects
|
||||
-----------------------------------------------------
|
||||
|
||||
Given structure descriptor and layout type, you can instantiate a
|
||||
"structure class" using uctypes.struct() factory function. From it,
|
||||
you can instantiate a specific structure instance at a given
|
||||
memory address. Memory address usually comes from following sources:
|
||||
|
||||
* Predefined address, when accessing hardware registers on a baremetal
|
||||
port. Lookup these addresses in datasheet for a particular MCU/SoC.
|
||||
* As return value from a call to some FFI (Foreign Function Interface)
|
||||
function.
|
||||
* From uctypes.addressof(), when you want to pass arguments to FFI
|
||||
function, or alternatively, to access some data for I/O (for example,
|
||||
data read from file or network socket).
|
||||
|
||||
Structure objects
|
||||
-----------------
|
||||
|
||||
|
||||
484
docs/make.bat
484
docs/make.bat
@@ -1,242 +1,242 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\MicroPython.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\MicroPython.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\MicroPython.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\MicroPython.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
|
||||
@@ -15,12 +15,16 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <string.h>
|
||||
#include "cc3000_common.h"
|
||||
#include "socket.h"
|
||||
#include "inet_ntop.h"
|
||||
|
||||
// We can't include stdio.h because it defines _types_fd_set, but we
|
||||
// need to use the CC3000 version of this type. So we must provide
|
||||
// our own declaration of snprintf. Grrr.
|
||||
int snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
|
||||
#define IN6ADDRSZ 16
|
||||
#define INADDRSZ 4
|
||||
#define INT16SZ 2
|
||||
|
||||
@@ -6,6 +6,9 @@ QSTR_DEFS = qstrdefsport.h #$(BUILD)/pins_qstr.h
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
||||
MAKE_FROZEN = ../tools/make-frozen.py
|
||||
|
||||
SCRIPTDIR = scripts
|
||||
PORT = /dev/ttyACM0
|
||||
CROSS_COMPILE = xtensa-lx106-elf-
|
||||
ESP_SDK = $(shell $(CC) -print-sysroot)/usr
|
||||
@@ -14,15 +17,20 @@ INC = -I.
|
||||
INC += -I..
|
||||
INC += -I../stmhal
|
||||
INC += -I../lib/mp-readline
|
||||
INC += -I../lib/netutils
|
||||
INC += -I../lib/timeutils
|
||||
INC += -I$(BUILD)
|
||||
INC += -I$(ESP_SDK)/include
|
||||
|
||||
UART_OS = 1
|
||||
|
||||
CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \
|
||||
-D__ets__ -DICACHE_FLASH \
|
||||
-fno-inline-functions \
|
||||
-Wl,-EL -mlongcalls -mtext-section-literals \
|
||||
|
||||
CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_XTENSA) $(COPT)
|
||||
CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \
|
||||
$(CFLAGS_XTENSA) $(COPT)
|
||||
|
||||
LDFLAGS = -nostdlib -T esp8266.ld -Map=$(@:.elf=.map) --cref
|
||||
LIBS = -L$(ESP_SDK)/lib -lmain -ljson -llwip -lpp -lnet80211 -lwpa -lphy -lnet80211
|
||||
@@ -48,17 +56,23 @@ SRC_C = \
|
||||
uart.c \
|
||||
modpyb.c \
|
||||
modpybpin.c \
|
||||
modpybrtc.c \
|
||||
modesp.c \
|
||||
modutime.c \
|
||||
utils.c \
|
||||
$(BUILD)/frozen.c \
|
||||
|
||||
STM_SRC_C = $(addprefix stmhal/,\
|
||||
printf.c \
|
||||
string0.c \
|
||||
pyexec.c \
|
||||
pybstdio.c \
|
||||
)
|
||||
|
||||
LIB_SRC_C = $(addprefix lib/,\
|
||||
libc/string0.c \
|
||||
mp-readline/readline.c \
|
||||
netutils/netutils.c \
|
||||
timeutils/timeutils.c \
|
||||
)
|
||||
|
||||
SRC_S = \
|
||||
@@ -74,6 +88,21 @@ OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
|
||||
|
||||
all: $(BUILD)/firmware-combined.bin
|
||||
|
||||
CONFVARS_FILE = $(BUILD)/confvars
|
||||
|
||||
ifeq ($(wildcard $(CONFVARS_FILE)),)
|
||||
$(shell $(MKDIR) -p $(BUILD))
|
||||
$(shell echo $(SCRIPTDIR) $(UART_OS) > $(CONFVARS_FILE))
|
||||
else ifneq ($(shell cat $(CONFVARS_FILE)), $(SCRIPTDIR) $(UART_OS))
|
||||
$(shell echo $(SCRIPTDIR) $(UART_OS) > $(CONFVARS_FILE))
|
||||
endif
|
||||
|
||||
$(BUILD)/uart.o: $(CONFVARS_FILE)
|
||||
|
||||
$(BUILD)/frozen.c: $(wildcard $(SCRIPTDIR)/*) $(CONFVARS_FILE)
|
||||
$(ECHO) "Generating $@"
|
||||
$(Q)$(MAKE_FROZEN) $(SCRIPTDIR) > $@
|
||||
|
||||
.PHONY: deploy
|
||||
|
||||
deploy: $(BUILD)/firmware-combined.bin
|
||||
|
||||
@@ -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 = 0x40210000, len = 0x40000
|
||||
irom0_0_seg : org = 0x40210000, len = 0x5A000
|
||||
}
|
||||
|
||||
/* define the top of RAM */
|
||||
@@ -79,9 +79,13 @@ SECTIONS
|
||||
*pyexec.o(.literal*, .text*)
|
||||
*readline.o(.literal*, .text*)
|
||||
*pybstdio.o(.literal*, .text*)
|
||||
*modpyb.o(.literal*, .text*)
|
||||
*gccollect.o(.literal* .text*)
|
||||
*gchelper.o(.literal* .text*)
|
||||
*modpyb.o(.literal*, .text*)
|
||||
*modpybpin.o(.literal*, .text*)
|
||||
*modpybrtc.o(.literal*, .text*)
|
||||
*modesp.o(.literal* .text*)
|
||||
*modutime.o(.literal* .text*)
|
||||
|
||||
/* we put as much rodata as possible in this section */
|
||||
/* note that only rodata accessed as a machine word is allowed here */
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "etshal.h"
|
||||
#include "uart.h"
|
||||
#include "esp_mphal.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
extern void ets_wdt_disable(void);
|
||||
extern void wdt_feed(void);
|
||||
@@ -82,8 +83,7 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) {
|
||||
}
|
||||
|
||||
uint32_t HAL_GetTick(void) {
|
||||
// TODO
|
||||
return 0;
|
||||
return system_get_time() / 1000;
|
||||
}
|
||||
|
||||
void HAL_Delay(uint32_t Delay) {
|
||||
|
||||
@@ -29,17 +29,12 @@
|
||||
#include "py/gc.h"
|
||||
#include "gccollect.h"
|
||||
|
||||
STATIC uint32_t stack_end;
|
||||
// As we do not have control over the application entry point, there is no way
|
||||
// to figure out the real stack base on runtime, so it needs to be hardcoded
|
||||
#define STACK_END 0x40000000
|
||||
|
||||
mp_uint_t gc_helper_get_regs_and_sp(mp_uint_t *regs);
|
||||
|
||||
void gc_collect_init(void) {
|
||||
mp_uint_t regs[8];
|
||||
mp_uint_t sp = gc_helper_get_regs_and_sp(regs);
|
||||
stack_end = sp;
|
||||
//printf("stack=%p ram_end=%p %d\n", stack_end, &_ram_end);
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
// start the GC
|
||||
gc_collect_start();
|
||||
@@ -53,7 +48,7 @@ void gc_collect(void) {
|
||||
mp_uint_t sp = gc_helper_get_regs_and_sp(regs);
|
||||
|
||||
// trace the stack, including the registers (since they live on the stack in this function)
|
||||
gc_collect_root((void**)sp, (stack_end - sp) / sizeof(uint32_t));
|
||||
gc_collect_root((void**)sp, (STACK_END - sp) / sizeof(uint32_t));
|
||||
|
||||
// end the GC
|
||||
gc_collect_end();
|
||||
|
||||
@@ -37,5 +37,4 @@ extern uint32_t _bss_end;
|
||||
extern uint32_t _heap_start;
|
||||
extern uint32_t _heap_end;
|
||||
|
||||
void gc_collect_init(void);
|
||||
void gc_collect(void);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/frozenmod.h"
|
||||
#include "py/gc.h"
|
||||
#include "pyexec.h"
|
||||
#include "gccollect.h"
|
||||
@@ -39,40 +40,33 @@
|
||||
|
||||
STATIC char heap[16384];
|
||||
|
||||
void user_init(void) {
|
||||
soft_reset:
|
||||
STATIC void mp_reset(void) {
|
||||
mp_stack_set_limit(10240);
|
||||
mp_hal_init();
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
gc_collect_init();
|
||||
mp_init();
|
||||
mp_obj_list_init(mp_sys_path, 0);
|
||||
mp_obj_list_init(mp_sys_argv, 0);
|
||||
|
||||
printf("\n");
|
||||
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
pyexec_friendly_repl_init();
|
||||
uart_task_init();
|
||||
return;
|
||||
goto soft_reset;
|
||||
#else
|
||||
for (;;) {
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
if (pyexec_raw_repl() != 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pyexec_friendly_repl() != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goto soft_reset;
|
||||
#if MICROPY_MODULE_FROZEN
|
||||
mp_lexer_t *lex = mp_find_frozen_module("main", 4);
|
||||
mp_parse_compile_execute(lex, MP_PARSE_FILE_INPUT, mp_globals_get(), mp_locals_get());
|
||||
#endif
|
||||
}
|
||||
|
||||
void soft_reset(void) {
|
||||
mp_hal_stdout_tx_str("PYB: soft reset\r\n");
|
||||
mp_hal_udelay(10000); // allow UART to flush output
|
||||
mp_reset();
|
||||
pyexec_event_repl_init();
|
||||
}
|
||||
|
||||
void user_init(void) {
|
||||
mp_reset();
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
pyexec_event_repl_init();
|
||||
uart_task_init();
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
481
esp8266/modesp.c
481
esp8266/modesp.c
@@ -32,14 +32,456 @@
|
||||
#include "py/obj.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/pfenv.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "netutils.h"
|
||||
#include "queue.h"
|
||||
#include "user_interface.h"
|
||||
#include "espconn.h"
|
||||
#include "utils.h"
|
||||
|
||||
// Singleton instance of scan callback, meaning that there can be only
|
||||
// one concurrent AP scan.
|
||||
STATIC mp_obj_t scan_cb_obj;
|
||||
STATIC const mp_obj_type_t esp_socket_type;
|
||||
|
||||
typedef struct _esp_socket_obj_t {
|
||||
mp_obj_base_t base;
|
||||
struct espconn *espconn;
|
||||
|
||||
mp_obj_t cb_connect;
|
||||
mp_obj_t cb_recv;
|
||||
mp_obj_t cb_sent;
|
||||
mp_obj_t cb_disconnect;
|
||||
|
||||
uint8_t *recvbuf;
|
||||
mp_uint_t recvbuf_len;
|
||||
|
||||
bool fromserver;
|
||||
|
||||
mp_obj_list_t *connlist;
|
||||
} esp_socket_obj_t;
|
||||
|
||||
// Due to the onconnect callback not being able to recognize the parent esp_socket,
|
||||
// we can have only one esp_socket listening at a time
|
||||
// This should be solvable by some PIC hacking
|
||||
STATIC esp_socket_obj_t *esp_socket_listening;
|
||||
|
||||
STATIC mp_obj_t esp_socket_make_new_base() {
|
||||
esp_socket_obj_t *s = m_new_obj_with_finaliser(esp_socket_obj_t);
|
||||
s->recvbuf = NULL;
|
||||
s->base.type = (mp_obj_t)&esp_socket_type;
|
||||
s->cb_connect = mp_const_none;
|
||||
s->cb_recv = mp_const_none;
|
||||
s->cb_disconnect = mp_const_none;
|
||||
s->cb_sent = mp_const_none;
|
||||
s->fromserver = false;
|
||||
s->connlist = NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
// constructor esp_socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
|
||||
// Arguments ignored as we do not support UDP (yet)
|
||||
STATIC mp_obj_t esp_socket_make_new(mp_obj_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, 4, false);
|
||||
|
||||
esp_socket_obj_t *s = esp_socket_make_new_base();
|
||||
s->espconn = m_new_obj(struct espconn);
|
||||
espconn_create(s->espconn);
|
||||
|
||||
s->espconn->reverse = s;
|
||||
// TODO: UDP Support
|
||||
s->espconn->type = ESPCONN_TCP;
|
||||
s->espconn->state = ESPCONN_NONE;
|
||||
|
||||
s->espconn->proto.tcp = m_new_obj(esp_tcp);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// method socket.close()
|
||||
STATIC mp_obj_t esp_socket_close(mp_obj_t self_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
if (esp_socket_listening == s) {
|
||||
esp_socket_listening = NULL;
|
||||
}
|
||||
|
||||
if (s->espconn->state != ESPCONN_NONE && s->espconn->state != ESPCONN_CLOSE) {
|
||||
espconn_disconnect(s->espconn);
|
||||
}
|
||||
|
||||
if (s->connlist != NULL) {
|
||||
mp_obj_list_set_len(s->connlist, 0);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_socket_close_obj, esp_socket_close);
|
||||
|
||||
// method socket.__del__()
|
||||
STATIC mp_obj_t esp_socket___del__(mp_obj_t self_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
esp_socket_close(self_in);
|
||||
|
||||
if (s->fromserver) {
|
||||
espconn_delete(s->espconn);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_socket___del___obj, esp_socket___del__);
|
||||
|
||||
// method socket.bind(address)
|
||||
STATIC mp_obj_t esp_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in,
|
||||
s->espconn->proto.tcp->remote_ip, NETUTILS_BIG);
|
||||
s->espconn->proto.tcp->local_port = port;
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_bind_obj, esp_socket_bind);
|
||||
|
||||
STATIC void esp_socket_recv_callback(void *arg, char *pdata, unsigned short len) {
|
||||
struct espconn *conn = arg;
|
||||
esp_socket_obj_t *s = conn->reverse;
|
||||
|
||||
if (s->cb_recv != mp_const_none) {
|
||||
call_function_2_protected(s->cb_recv, s, mp_obj_new_bytes((byte *)pdata, len));
|
||||
} else {
|
||||
if (s->recvbuf == NULL) {
|
||||
s->recvbuf = gc_alloc(len, false);
|
||||
s->recvbuf_len = len;
|
||||
if (s->recvbuf != NULL) {
|
||||
memcpy(s->recvbuf, pdata, len);
|
||||
}
|
||||
} else {
|
||||
s->recvbuf = gc_realloc(s->recvbuf, s->recvbuf_len + len);
|
||||
if (s->recvbuf != NULL) {
|
||||
memcpy(&s->recvbuf[s->recvbuf_len], pdata, len);
|
||||
s->recvbuf_len += len;
|
||||
}
|
||||
}
|
||||
if (s->recvbuf == NULL) {
|
||||
esp_socket_close(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void esp_socket_sent_callback(void *arg) {
|
||||
struct espconn *conn = arg;
|
||||
esp_socket_obj_t *s = conn->reverse;
|
||||
|
||||
if (s->cb_sent != mp_const_none) {
|
||||
call_function_1_protected(s->cb_sent, s);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void esp_socket_disconnect_callback(void *arg) {
|
||||
struct espconn *conn = arg;
|
||||
esp_socket_obj_t *s = conn->reverse;
|
||||
|
||||
if (s->cb_disconnect != mp_const_none) {
|
||||
call_function_1_protected(s->cb_disconnect, s);
|
||||
}
|
||||
|
||||
esp_socket_close(s);
|
||||
}
|
||||
|
||||
STATIC void esp_socket_connect_callback_server(void *arg) {
|
||||
struct espconn *conn = arg;
|
||||
|
||||
esp_socket_obj_t *s = esp_socket_make_new_base();
|
||||
s->espconn = conn;
|
||||
s->fromserver = true;
|
||||
conn->reverse = s;
|
||||
|
||||
espconn_regist_recvcb(conn, esp_socket_recv_callback);
|
||||
espconn_regist_sentcb(conn, esp_socket_sent_callback);
|
||||
espconn_regist_disconcb(conn, esp_socket_disconnect_callback);
|
||||
espconn_regist_time(conn, 15, 0);
|
||||
|
||||
if (esp_socket_listening->cb_connect != mp_const_none) {
|
||||
call_function_1_protected(esp_socket_listening->cb_connect, s);
|
||||
} else {
|
||||
mp_obj_list_append(esp_socket_listening->connlist, s);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void esp_socket_connect_callback_client(void *arg) {
|
||||
struct espconn *conn = arg;
|
||||
esp_socket_obj_t *s = conn->reverse;
|
||||
|
||||
if (s->cb_connect != mp_const_none) {
|
||||
call_function_1_protected(s->cb_connect, s);
|
||||
}
|
||||
}
|
||||
|
||||
// method socket.listen(backlog)
|
||||
STATIC mp_obj_t esp_socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
if (esp_socket_listening != NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
"only one espconn can listen at a time"));
|
||||
}
|
||||
|
||||
esp_socket_listening = s;
|
||||
|
||||
s->connlist = mp_obj_new_list(0, NULL);
|
||||
|
||||
espconn_regist_connectcb(s->espconn, esp_socket_connect_callback_server);
|
||||
espconn_accept(s->espconn);
|
||||
espconn_regist_time(s->espconn, 1500, 0);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_listen_obj, esp_socket_listen);
|
||||
|
||||
// method socket.accept()
|
||||
STATIC mp_obj_t esp_socket_accept(mp_obj_t self_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
if (s->connlist == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
"not listening"));
|
||||
}
|
||||
|
||||
do {
|
||||
mp_uint_t len;
|
||||
mp_obj_t *items;
|
||||
|
||||
mp_obj_list_get(s->connlist, &len, &items);
|
||||
if (len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
esp_socket_obj_t *rs = items[0];
|
||||
mp_obj_list_remove(s->connlist, rs);
|
||||
if (rs->espconn->state != ESPCONN_CLOSE) {
|
||||
return rs;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
"no connection in queue"));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_socket_accept_obj, esp_socket_accept);
|
||||
|
||||
// method socket.connect(address)
|
||||
STATIC mp_obj_t esp_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
if (s->espconn == NULL || s->espconn->state != ESPCONN_NONE) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
"transport endpoint is already connected or closed"));
|
||||
}
|
||||
|
||||
espconn_regist_connectcb(s->espconn, esp_socket_connect_callback_client);
|
||||
espconn_regist_recvcb(s->espconn, esp_socket_recv_callback);
|
||||
espconn_regist_sentcb(s->espconn, esp_socket_sent_callback);
|
||||
espconn_regist_disconcb(s->espconn, esp_socket_disconnect_callback);
|
||||
|
||||
s->espconn->proto.tcp->remote_port =
|
||||
netutils_parse_inet_addr(addr_in, s->espconn->proto.tcp->remote_ip,
|
||||
NETUTILS_BIG);
|
||||
espconn_connect(s->espconn);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_connect_obj, esp_socket_connect);
|
||||
|
||||
// method socket.send(bytes)
|
||||
STATIC mp_obj_t esp_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
if (s->espconn->state == ESPCONN_NONE || s->espconn->state == ESPCONN_CLOSE) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
"not connected"));
|
||||
}
|
||||
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
espconn_sent(s->espconn, bufinfo.buf, bufinfo.len);
|
||||
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_send_obj, esp_socket_send);
|
||||
|
||||
// method socket.recv(bufsize)
|
||||
STATIC mp_obj_t esp_socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
|
||||
if (s->recvbuf == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
"no data available"));
|
||||
}
|
||||
|
||||
mp_uint_t mxl = mp_obj_get_int(len_in);
|
||||
if (mxl >= s->recvbuf_len) {
|
||||
mp_obj_t trt = mp_obj_new_bytes(s->recvbuf, s->recvbuf_len);
|
||||
gc_free(s->recvbuf);
|
||||
s->recvbuf = NULL;
|
||||
return trt;
|
||||
} else {
|
||||
mp_obj_t trt = mp_obj_new_bytes(s->recvbuf, mxl);
|
||||
memmove(s->recvbuf, &s->recvbuf[mxl], s->recvbuf_len - mxl);
|
||||
s->recvbuf_len -= mxl;
|
||||
s->recvbuf = gc_realloc(s->recvbuf, s->recvbuf_len);
|
||||
return trt;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_recv_obj, esp_socket_recv);
|
||||
|
||||
// method socket.sendto(bytes, address)
|
||||
STATIC mp_obj_t esp_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "UDP not supported"));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_socket_sendto_obj, esp_socket_sendto);
|
||||
|
||||
// method socket.recvfrom(bufsize)
|
||||
STATIC mp_obj_t esp_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "UDP not supported"));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_recvfrom_obj, esp_socket_recvfrom);
|
||||
|
||||
STATIC mp_obj_t esp_socket_onconnect(mp_obj_t self_in, mp_obj_t lambda_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
s->cb_connect = lambda_in;
|
||||
|
||||
if (s->connlist != NULL) {
|
||||
do {
|
||||
mp_uint_t len;
|
||||
mp_obj_t *items;
|
||||
|
||||
mp_obj_list_get(s->connlist, &len, &items);
|
||||
if (len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
esp_socket_obj_t *rs = items[0];
|
||||
mp_obj_list_remove(s->connlist, rs);
|
||||
if (s->espconn->state != ESPCONN_CLOSE) {
|
||||
call_function_1_protected(s->cb_connect, rs);
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_onconnect_obj, esp_socket_onconnect);
|
||||
|
||||
STATIC mp_obj_t esp_socket_onrecv(mp_obj_t self_in, mp_obj_t lambda_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
s->cb_recv = lambda_in;
|
||||
if (s->recvbuf != NULL) {
|
||||
call_function_2_protected(s->cb_recv, s,
|
||||
mp_obj_new_bytes((byte *)s->recvbuf, s->recvbuf_len));
|
||||
s->recvbuf = NULL;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_onrecv_obj, esp_socket_onrecv);
|
||||
|
||||
STATIC mp_obj_t esp_socket_onsent(mp_obj_t self_in, mp_obj_t lambda_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
s->cb_sent = lambda_in;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_onsent_obj, esp_socket_onsent);
|
||||
|
||||
STATIC mp_obj_t esp_socket_ondisconnect(mp_obj_t self_in, mp_obj_t lambda_in) {
|
||||
esp_socket_obj_t *s = self_in;
|
||||
s->cb_disconnect = lambda_in;
|
||||
|
||||
if (s->espconn->state == ESPCONN_CLOSE) {
|
||||
call_function_1_protected(s->cb_disconnect, s);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_ondisconnect_obj, esp_socket_ondisconnect);
|
||||
|
||||
typedef struct _esp_getaddrinfo_cb_struct_t {
|
||||
mp_obj_t lambda;
|
||||
mp_uint_t port;
|
||||
} esp_getaddrinfo_cb_struct_t;
|
||||
|
||||
STATIC esp_getaddrinfo_cb_struct_t esp_getaddrinfo_cb_struct;
|
||||
|
||||
STATIC void esp_getaddrinfo_cb(const char *name, ip_addr_t *ipaddr, void *arg) {
|
||||
mp_obj_t namestr = mp_obj_new_str(name, strlen(name), true);
|
||||
if (ipaddr != NULL) {
|
||||
uint8_t ip[4];
|
||||
ip[0] = (ipaddr->addr >> 24) & 0xff;
|
||||
ip[1] = (ipaddr->addr >> 16) & 0xff;
|
||||
ip[2] = (ipaddr->addr >> 8) & 0xff;
|
||||
ip[3] = (ipaddr->addr >> 0) & 0xff;
|
||||
|
||||
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
|
||||
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||
tuple->items[4] = netutils_format_inet_addr(ip,
|
||||
esp_getaddrinfo_cb_struct.port, NETUTILS_LITTLE);
|
||||
call_function_2_protected(esp_getaddrinfo_cb_struct.lambda, namestr, tuple);
|
||||
} else {
|
||||
call_function_2_protected(esp_getaddrinfo_cb_struct.lambda, namestr, mp_const_none);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in,
|
||||
mp_obj_t lambda_in) {
|
||||
mp_uint_t hlen;
|
||||
const char *host = mp_obj_str_get_data(host_in, &hlen);
|
||||
ip_addr_t ipaddr;
|
||||
|
||||
esp_getaddrinfo_cb_struct.lambda = lambda_in;
|
||||
esp_getaddrinfo_cb_struct.port = mp_obj_get_int(port_in);
|
||||
|
||||
err_t ret = espconn_gethostbyname(NULL, host, &ipaddr,
|
||||
esp_getaddrinfo_cb);
|
||||
|
||||
if (ret == ESPCONN_OK) {
|
||||
esp_getaddrinfo_cb(host, &ipaddr, NULL);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_getaddrinfo_obj, esp_getaddrinfo);
|
||||
|
||||
STATIC const mp_map_elem_t esp_socket_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&esp_socket___del___obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&esp_socket_close_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&esp_socket_bind_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&esp_socket_listen_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&esp_socket_accept_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&esp_socket_connect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&esp_socket_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&esp_socket_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&esp_socket_sendto_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&esp_socket_recvfrom_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_onconnect), (mp_obj_t)&esp_socket_onconnect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_onrecv), (mp_obj_t)&esp_socket_onrecv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_onsent), (mp_obj_t)&esp_socket_onsent_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ondisconnect), (mp_obj_t)&esp_socket_ondisconnect_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(esp_socket_locals_dict, esp_socket_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t esp_socket_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_socket,
|
||||
.make_new = esp_socket_make_new,
|
||||
.locals_dict = (mp_obj_t)&esp_socket_locals_dict,
|
||||
};
|
||||
|
||||
#define MODESP_INCLUDE_CONSTANTS (1)
|
||||
|
||||
static void error_check(bool status, const char *msg) {
|
||||
if (!status) {
|
||||
@@ -47,16 +489,6 @@ static void error_check(bool status, const char *msg) {
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t call_function_1_protected(mp_obj_t fun, mp_obj_t arg) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
return mp_call_function_1(fun, arg);
|
||||
} else {
|
||||
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
|
||||
return (mp_obj_t)nlr.ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void esp_scan_cb(scaninfo *si, STATUS status) {
|
||||
//printf("in pyb_scan_cb: %d, si=%p, si->pbss=%p\n", status, si, si->pbss);
|
||||
struct bss_info *bs;
|
||||
@@ -69,13 +501,13 @@ STATIC void esp_scan_cb(scaninfo *si, STATUS status) {
|
||||
t->items[3] = MP_OBJ_NEW_SMALL_INT(bs->rssi);
|
||||
t->items[4] = MP_OBJ_NEW_SMALL_INT(bs->authmode);
|
||||
t->items[5] = MP_OBJ_NEW_SMALL_INT(bs->is_hidden);
|
||||
call_function_1_protected(scan_cb_obj, t);
|
||||
call_function_1_protected(MP_STATE_PORT(scan_cb_obj), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_scan(mp_obj_t cb_in) {
|
||||
scan_cb_obj = cb_in;
|
||||
MP_STATE_PORT(scan_cb_obj) = cb_in;
|
||||
wifi_set_opmode(STATION_MODE);
|
||||
wifi_station_scan(NULL, (scan_done_cb_t)esp_scan_cb);
|
||||
return mp_const_none;
|
||||
@@ -117,6 +549,23 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disconnect), (mp_obj_t)&esp_disconnect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&esp_scan_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_status), (mp_obj_t)&esp_status_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&esp_getaddrinfo_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&esp_socket_type },
|
||||
|
||||
#if MODESP_INCLUDE_CONSTANTS
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STAT_IDLE),
|
||||
MP_OBJ_NEW_SMALL_INT(STATION_IDLE)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STAT_CONNECTING),
|
||||
MP_OBJ_NEW_SMALL_INT(STATION_CONNECTING)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STAT_WRONG_PASSWORD),
|
||||
MP_OBJ_NEW_SMALL_INT(STATION_WRONG_PASSWORD)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STAT_NO_AP_FOUND),
|
||||
MP_OBJ_NEW_SMALL_INT(STATION_NO_AP_FOUND)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STAT_CONNECT_FAIL),
|
||||
MP_OBJ_NEW_SMALL_INT(STATION_CONNECT_FAIL)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STAT_GOT_IP),
|
||||
MP_OBJ_NEW_SMALL_INT(STATION_GOT_IP)},
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(esp_module_globals, esp_module_globals_table);
|
||||
|
||||
@@ -81,7 +81,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj, 0, 1, pyb_info);
|
||||
STATIC mp_obj_t pyb_freq(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// get
|
||||
return mp_obj_new_int(mp_hal_get_cpu_freq());
|
||||
return mp_obj_new_int(mp_hal_get_cpu_freq() * 1000000);
|
||||
} else {
|
||||
// set
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't change freq"));
|
||||
@@ -108,13 +108,13 @@ STATIC mp_obj_t pyb_elapsed_millis(mp_obj_t start) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_millis_obj, pyb_elapsed_millis);
|
||||
|
||||
STATIC mp_obj_t pyb_micros(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
return MP_OBJ_NEW_SMALL_INT(system_get_time());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_micros_obj, pyb_micros);
|
||||
|
||||
STATIC mp_obj_t pyb_elapsed_micros(mp_obj_t start) {
|
||||
uint32_t startMicros = mp_obj_get_int(start);
|
||||
uint32_t currMicros = 0;
|
||||
uint32_t currMicros = system_get_time();
|
||||
return MP_OBJ_NEW_SMALL_INT((currMicros - startMicros) & 0x3fffffff);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_micros_obj, pyb_elapsed_micros);
|
||||
@@ -159,6 +159,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hard_reset), (mp_obj_t)&pyb_hard_reset_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pyb_pin_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
extern const mp_obj_type_t pyb_pin_type;
|
||||
extern const mp_obj_base_t pyb_rtc_obj;
|
||||
|
||||
@@ -65,11 +65,11 @@ STATIC const pyb_pin_obj_t pyb_pin_obj[] = {
|
||||
{{&pyb_pin_type}, 15, 15, PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15},
|
||||
};
|
||||
|
||||
STATIC void pyb_pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pyb_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
|
||||
// pin name
|
||||
print(env, "Pin(%u)", self->pin_id);
|
||||
mp_printf(print, "Pin(%u)", self->pin_id);
|
||||
}
|
||||
|
||||
// pin.init(mode, pull=Pin.PULL_NONE, af=-1)
|
||||
|
||||
167
esp8266/modpybrtc.c
Normal file
167
esp8266/modpybrtc.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
*
|
||||
* 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 MICROPY_HAL_H
|
||||
#include "timeutils.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
typedef struct _pyb_rtc_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} pyb_rtc_obj_t;
|
||||
|
||||
#define MEM_MAGIC 0x75507921
|
||||
#define MEM_DELTA_ADDR 64
|
||||
#define MEM_CAL_ADDR (MEM_DELTA_ADDR + 2)
|
||||
#define MEM_USER_MAGIC_ADDR (MEM_CAL_ADDR + 1)
|
||||
#define MEM_USER_LEN_ADDR (MEM_USER_MAGIC_ADDR + 1)
|
||||
#define MEM_USER_DATA_ADDR (MEM_USER_LEN_ADDR + 1)
|
||||
#define MEM_USER_MAXLEN (512 - (MEM_USER_DATA_ADDR - MEM_DELTA_ADDR) * 4)
|
||||
|
||||
STATIC uint64_t pyb_rtc_raw_us(uint64_t cal) {
|
||||
return system_get_rtc_time() * ((cal >> 12) * 1000 + (cal & 0xfff) / 4) / 1000;
|
||||
};
|
||||
|
||||
void pyb_rtc_set_us_since_2000(uint64_t nowus) {
|
||||
uint32_t cal = system_rtc_clock_cali_proc();
|
||||
int64_t delta = nowus - pyb_rtc_raw_us(cal);
|
||||
|
||||
// As the calibration value jitters quite a bit, to make the
|
||||
// clock at least somewhat practially usable, we need to store it
|
||||
system_rtc_mem_write(MEM_CAL_ADDR, &cal, sizeof(cal));
|
||||
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
|
||||
};
|
||||
|
||||
uint64_t pyb_rtc_get_us_since_2000() {
|
||||
uint32_t cal;
|
||||
int64_t delta;
|
||||
|
||||
system_rtc_mem_read(MEM_CAL_ADDR, &cal, sizeof(cal));
|
||||
system_rtc_mem_read(MEM_DELTA_ADDR, &delta, sizeof(delta));
|
||||
|
||||
return pyb_rtc_raw_us(cal) + delta;
|
||||
};
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 1) {
|
||||
// Get time
|
||||
uint64_t msecs = pyb_rtc_get_us_since_2000() / 1000;
|
||||
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(msecs / 1000, &tm);
|
||||
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
mp_obj_new_int(tm.tm_mon),
|
||||
mp_obj_new_int(tm.tm_mday),
|
||||
mp_obj_new_int(tm.tm_wday),
|
||||
mp_obj_new_int(tm.tm_hour),
|
||||
mp_obj_new_int(tm.tm_min),
|
||||
mp_obj_new_int(tm.tm_sec),
|
||||
mp_obj_new_int(msecs % 1000)
|
||||
};
|
||||
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
} else {
|
||||
// Set time
|
||||
mp_obj_t *items;
|
||||
mp_obj_get_array_fixed_n(args[1], 8, &items);
|
||||
|
||||
pyb_rtc_set_us_since_2000(
|
||||
((uint64_t)timeutils_seconds_since_2000(
|
||||
mp_obj_get_int(items[0]),
|
||||
mp_obj_get_int(items[1]),
|
||||
mp_obj_get_int(items[2]),
|
||||
mp_obj_get_int(items[4]),
|
||||
mp_obj_get_int(items[5]),
|
||||
mp_obj_get_int(items[6])) * 1000 + mp_obj_get_int(items[7])) * 1000);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_memory(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
uint8_t rtcram[MEM_USER_MAXLEN];
|
||||
uint32_t len;
|
||||
uint32_t magic;
|
||||
|
||||
if (n_args == 1) {
|
||||
|
||||
system_rtc_mem_read(MEM_USER_MAGIC_ADDR, &magic, sizeof(magic));
|
||||
if (magic != MEM_MAGIC) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
system_rtc_mem_read(MEM_USER_LEN_ADDR, &len, sizeof(len));
|
||||
system_rtc_mem_read(MEM_USER_DATA_ADDR, rtcram, len + (4 - len % 4));
|
||||
|
||||
return mp_obj_new_bytes(rtcram, len);
|
||||
} else {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
if (bufinfo.len > MEM_USER_MAXLEN) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
|
||||
"buffer too long"));
|
||||
}
|
||||
|
||||
magic = MEM_MAGIC;
|
||||
system_rtc_mem_write(MEM_USER_MAGIC_ADDR, &magic, sizeof(len));
|
||||
len = bufinfo.len;
|
||||
system_rtc_mem_write(MEM_USER_LEN_ADDR, &len, sizeof(len));
|
||||
|
||||
int i = 0;
|
||||
for (; i < bufinfo.len; i++) {
|
||||
rtcram[i] = ((uint8_t *)bufinfo.buf)[i];
|
||||
}
|
||||
|
||||
system_rtc_mem_write(MEM_USER_DATA_ADDR, rtcram, len + (4 - len % 4));
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_memory_obj, 1, 2, pyb_rtc_memory);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_memory), (mp_obj_t)&pyb_rtc_memory_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pyb_rtc_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_RTC,
|
||||
.locals_dict = (mp_obj_t)&pyb_rtc_locals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type};
|
||||
29
esp8266/modpybrtc.h
Normal file
29
esp8266/modpybrtc.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void pyb_rtc_set_us_since_2000(uint64_t nowus);
|
||||
|
||||
uint64_t pyb_rtc_get_us_since_2000();
|
||||
132
esp8266/modutime.c
Normal file
132
esp8266/modutime.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
*
|
||||
* 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/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "modpyb.h"
|
||||
#include "modpybrtc.h"
|
||||
#include "timeutils.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
/// \module time - time related functions
|
||||
///
|
||||
/// The `time` module provides functions for getting the current time and date,
|
||||
/// and for sleeping.
|
||||
|
||||
/// \function localtime([secs])
|
||||
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
|
||||
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
|
||||
/// If secs is not provided or None, then the current time from the RTC is used.
|
||||
/// year includes the century (for example 2014)
|
||||
/// month is 1-12
|
||||
/// mday is 1-31
|
||||
/// hour is 0-23
|
||||
/// minute is 0-59
|
||||
/// second is 0-59
|
||||
/// weekday is 0-6 for Mon-Sun.
|
||||
/// yearday is 1-366
|
||||
STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
timeutils_struct_time_t tm;
|
||||
mp_int_t seconds;
|
||||
if (n_args == 0 || args[0] == mp_const_none) {
|
||||
seconds = pyb_rtc_get_us_since_2000() / 1000 / 1000;
|
||||
} else {
|
||||
seconds = mp_obj_get_int(args[0]);
|
||||
}
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
mp_obj_t tuple[8] = {
|
||||
tuple[0] = mp_obj_new_int(tm.tm_year),
|
||||
tuple[1] = mp_obj_new_int(tm.tm_mon),
|
||||
tuple[2] = mp_obj_new_int(tm.tm_mday),
|
||||
tuple[3] = mp_obj_new_int(tm.tm_hour),
|
||||
tuple[4] = mp_obj_new_int(tm.tm_min),
|
||||
tuple[5] = mp_obj_new_int(tm.tm_sec),
|
||||
tuple[6] = mp_obj_new_int(tm.tm_wday),
|
||||
tuple[7] = mp_obj_new_int(tm.tm_yday),
|
||||
};
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
|
||||
|
||||
/// \function mktime()
|
||||
/// This is inverse function of localtime. It's argument is a full 8-tuple
|
||||
/// which expresses a time as per localtime. It returns an integer which is
|
||||
/// the number of seconds since Jan 1, 2000.
|
||||
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
||||
mp_uint_t len;
|
||||
mp_obj_t *elem;
|
||||
mp_obj_get_array(tuple, &len, &elem);
|
||||
|
||||
// localtime generates a tuple of len 8. CPython uses 9, so we accept both.
|
||||
if (len < 8 || len > 9) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len));
|
||||
}
|
||||
|
||||
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
|
||||
mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]),
|
||||
mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
|
||||
|
||||
/// \function sleep(seconds)
|
||||
/// Sleep for the given number of seconds.
|
||||
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
||||
HAL_Delay(1000 * mp_obj_get_int(seconds_o));
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
|
||||
|
||||
/// \function time()
|
||||
/// Returns the number of seconds, as an integer, since 1/1/2000.
|
||||
STATIC mp_obj_t time_time(void) {
|
||||
// get date and time
|
||||
return mp_obj_new_int(pyb_rtc_get_us_since_2000() / 1000 / 1000);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
|
||||
STATIC const mp_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||
|
||||
const mp_obj_module_t utime_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_utime,
|
||||
.globals = (mp_obj_dict_t*)&time_module_globals,
|
||||
};
|
||||
@@ -14,6 +14,7 @@
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
@@ -36,6 +37,7 @@
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_MODULE_FROZEN (1)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
@@ -52,6 +54,9 @@ 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;
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len);
|
||||
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
@@ -60,15 +65,24 @@ extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
// extra built in modules to add to the list of known ones
|
||||
extern const struct _mp_obj_module_t pyb_module;
|
||||
extern const struct _mp_obj_module_t esp_module;
|
||||
extern const struct _mp_obj_module_t utime_module;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_utime), (mp_obj_t)&utime_module }, \
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&utime_module }, \
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
const char *readline_hist[8];
|
||||
const char *readline_hist[8]; \
|
||||
\
|
||||
/* Singleton instance of scan callback, meaning that there can
|
||||
be only one concurrent AP scan. */ \
|
||||
mp_obj_t scan_cb_obj; \
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#include <alloca.h>
|
||||
|
||||
@@ -42,10 +42,34 @@ Q(sync)
|
||||
Q(hard_reset)
|
||||
|
||||
Q(esp)
|
||||
Q(socket)
|
||||
Q(connect)
|
||||
Q(disconnect)
|
||||
Q(scan)
|
||||
Q(status)
|
||||
Q(getaddrinfo)
|
||||
Q(send)
|
||||
Q(sendto)
|
||||
Q(recv)
|
||||
Q(recvfrom)
|
||||
Q(listen)
|
||||
Q(accept)
|
||||
Q(bind)
|
||||
Q(settimeout)
|
||||
Q(setblocking)
|
||||
Q(setsockopt)
|
||||
Q(close)
|
||||
Q(protocol)
|
||||
Q(onconnect)
|
||||
Q(onrecv)
|
||||
Q(onsent)
|
||||
Q(ondisconnect)
|
||||
Q(STAT_IDLE)
|
||||
Q(STAT_CONNECTING)
|
||||
Q(STAT_WRONG_PASSWORD)
|
||||
Q(STAT_NO_AP_FOUND)
|
||||
Q(STAT_CONNECT_FAIL)
|
||||
Q(STAT_GOT_IP)
|
||||
|
||||
// Pin class
|
||||
Q(Pin)
|
||||
@@ -61,3 +85,15 @@ Q(OUT_OD)
|
||||
Q(PULL_NONE)
|
||||
Q(PULL_UP)
|
||||
Q(PULL_DOWN)
|
||||
|
||||
// RTC
|
||||
Q(RTC)
|
||||
Q(datetime)
|
||||
Q(memory)
|
||||
|
||||
// utime
|
||||
Q(utime)
|
||||
Q(localtime)
|
||||
Q(mktime)
|
||||
Q(sleep)
|
||||
Q(time)
|
||||
|
||||
1
esp8266/scripts/main.py
Normal file
1
esp8266/scripts/main.py
Normal file
@@ -0,0 +1 @@
|
||||
# This script is run on boot
|
||||
@@ -112,13 +112,13 @@ void uart_tx_one_char(uint8 uart, uint8 TxChar) {
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
static void ICACHE_FLASH_ATTR
|
||||
uart1_write_char(char c) {
|
||||
uart_os_write_char(char c) {
|
||||
if (c == '\n') {
|
||||
uart_tx_one_char(UART1, '\r');
|
||||
uart_tx_one_char(UART1, '\n');
|
||||
uart_tx_one_char(UART_OS, '\r');
|
||||
uart_tx_one_char(UART_OS, '\n');
|
||||
} else if (c == '\r') {
|
||||
} else {
|
||||
uart_tx_one_char(UART1, c);
|
||||
uart_tx_one_char(UART_OS, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ void ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br) {
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
||||
// install uart1 putc callback
|
||||
os_install_putc1((void *)uart1_write_char);
|
||||
os_install_putc1((void *)uart_os_write_char);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR uart_reattach() {
|
||||
@@ -200,10 +200,16 @@ void ICACHE_FLASH_ATTR uart_reattach() {
|
||||
|
||||
// Task-based UART interface
|
||||
|
||||
int pyexec_friendly_repl_process_char(int c);
|
||||
#include "py/obj.h"
|
||||
#include "stmhal/pyexec.h"
|
||||
|
||||
void soft_reset(void);
|
||||
|
||||
void uart_task_handler(os_event_t *evt) {
|
||||
pyexec_friendly_repl_process_char(evt->par);
|
||||
int ret = pyexec_event_repl_process_char(evt->par);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
soft_reset();
|
||||
}
|
||||
}
|
||||
|
||||
void uart_task_init() {
|
||||
|
||||
50
esp8266/utils.c
Normal file
50
esp8266/utils.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
* Copyright (c) 2015 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 "py/runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/nlr.h"
|
||||
|
||||
mp_obj_t call_function_1_protected(mp_obj_t fun, mp_obj_t arg) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
return mp_call_function_1(fun, arg);
|
||||
} else {
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
return (mp_obj_t)nlr.ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t call_function_2_protected(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
return mp_call_function_2(fun, arg1, arg2);
|
||||
} else {
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
return (mp_obj_t)nlr.ret_val;
|
||||
}
|
||||
}
|
||||
29
esp8266/utils.h
Normal file
29
esp8266/utils.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
mp_obj_t call_function_1_protected(mp_obj_t fun, mp_obj_t arg);
|
||||
mp_obj_t call_function_2_protected(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2);
|
||||
118
extmod/modmachine.c
Normal file
118
extmod/modmachine.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE
|
||||
|
||||
STATIC mp_uint_t get_read_addr(mp_obj_t addr_o, uint align) {
|
||||
mp_uint_t addr = mp_obj_int_get_truncated(addr_o);
|
||||
if ((addr & (align - 1)) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t get_write_addr(mp_obj_t addr_o, uint align) {
|
||||
mp_uint_t addr = mp_obj_int_get_truncated(addr_o);
|
||||
if ((addr & (align - 1)) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
typedef struct _machine_mem_obj_t {
|
||||
mp_obj_base_t base;
|
||||
unsigned elem_size; // in bytes
|
||||
} machine_mem_obj_t;
|
||||
|
||||
STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
machine_mem_obj_t *self = self_in;
|
||||
mp_printf(print, "<%u-bit memory>", 8 * self->elem_size);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
// TODO support slice index to read/write multiple values at once
|
||||
machine_mem_obj_t *self = self_in;
|
||||
if (value == MP_OBJ_NULL) {
|
||||
// delete
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
} else if (value == MP_OBJ_SENTINEL) {
|
||||
// load
|
||||
mp_uint_t addr = get_read_addr(index, self->elem_size);
|
||||
uint32_t val;
|
||||
switch (self->elem_size) {
|
||||
case 1: val = (*(uint8_t*)addr); break;
|
||||
case 2: val = (*(uint16_t*)addr); break;
|
||||
default: val = (*(uint32_t*)addr); break;
|
||||
}
|
||||
return mp_obj_new_int(val);
|
||||
} else {
|
||||
// store
|
||||
mp_uint_t addr = get_write_addr(index, self->elem_size);
|
||||
uint32_t val = mp_obj_get_int(value);
|
||||
switch (self->elem_size) {
|
||||
case 1: (*(uint8_t*)addr) = val; break;
|
||||
case 2: (*(uint16_t*)addr) = val; break;
|
||||
default: (*(uint32_t*)addr) = val; break;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const mp_obj_type_t machine_mem_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_mem,
|
||||
.print = machine_mem_print,
|
||||
.subscr = machine_mem_subscr,
|
||||
};
|
||||
|
||||
STATIC const machine_mem_obj_t machine_mem8_obj = {{&machine_mem_type}, 1};
|
||||
STATIC const machine_mem_obj_t machine_mem16_obj = {{&machine_mem_type}, 2};
|
||||
STATIC const machine_mem_obj_t machine_mem32_obj = {{&machine_mem_type}, 4};
|
||||
|
||||
STATIC const mp_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_machine) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem8), (mp_obj_t)&machine_mem8_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem16), (mp_obj_t)&machine_mem16_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem32), (mp_obj_t)&machine_mem32_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_machine = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_machine,
|
||||
.globals = (mp_obj_dict_t*)&machine_module_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_MACHINE
|
||||
@@ -137,7 +137,7 @@ STATIC mp_obj_t uctypes_struct_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_u
|
||||
return o;
|
||||
}
|
||||
|
||||
STATIC void uctypes_struct_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void uctypes_struct_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_uctypes_struct_t *self = self_in;
|
||||
const char *typen = "unk";
|
||||
@@ -154,7 +154,7 @@ STATIC void uctypes_struct_print(void (*print)(void *env, const char *fmt, ...),
|
||||
} else {
|
||||
typen = "ERROR";
|
||||
}
|
||||
print(env, "<struct %s %p>", typen, self->addr);
|
||||
mp_printf(print, "<struct %s %p>", typen, self->addr);
|
||||
}
|
||||
|
||||
// Get size of any type descriptor
|
||||
@@ -482,13 +482,17 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
|
||||
return MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
STATIC void uctypes_struct_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
mp_obj_t val = uctypes_struct_attr_op(self_in, attr, MP_OBJ_NULL);
|
||||
*dest = val;
|
||||
}
|
||||
|
||||
STATIC bool uctypes_struct_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t val) {
|
||||
return uctypes_struct_attr_op(self_in, attr, val) != MP_OBJ_NULL;
|
||||
STATIC void uctypes_struct_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
if (dest[0] == MP_OBJ_NULL) {
|
||||
// load attribute
|
||||
mp_obj_t val = uctypes_struct_attr_op(self_in, attr, MP_OBJ_NULL);
|
||||
dest[0] = val;
|
||||
} else {
|
||||
// delete/store attribute
|
||||
if (uctypes_struct_attr_op(self_in, attr, dest[1]) != MP_OBJ_NULL) {
|
||||
dest[0] = MP_OBJ_NULL; // indicate success
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
|
||||
@@ -589,8 +593,7 @@ STATIC const mp_obj_type_t uctypes_struct_type = {
|
||||
.name = MP_QSTR_struct,
|
||||
.print = uctypes_struct_print,
|
||||
.make_new = uctypes_struct_make_new,
|
||||
.load_attr = uctypes_struct_load_attr,
|
||||
.store_attr = uctypes_struct_store_attr,
|
||||
.attr = uctypes_struct_attr,
|
||||
.subscr = uctypes_struct_subscr,
|
||||
};
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@
|
||||
|
||||
STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
|
||||
vstr_t vstr;
|
||||
vstr_init(&vstr, 8);
|
||||
mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, &vstr, obj, PRINT_JSON);
|
||||
mp_print_t print;
|
||||
vstr_init_print(&vstr, 8, &print);
|
||||
mp_obj_print_helper(&print, obj, PRINT_JSON);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
|
||||
|
||||
@@ -51,15 +51,15 @@ typedef struct _mp_obj_match_t {
|
||||
} mp_obj_match_t;
|
||||
|
||||
|
||||
STATIC void match_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void match_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_match_t *self = self_in;
|
||||
print(env, "<match num=%d>", self->num_matches);
|
||||
mp_printf(print, "<match num=%d>", self->num_matches);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t match_group(mp_obj_t self_in, mp_obj_t no_in) {
|
||||
mp_obj_match_t *self = self_in;
|
||||
mp_int_t no = mp_obj_int_get_truncated(no_in);
|
||||
mp_int_t no = mp_obj_get_int(no_in);
|
||||
if (no < 0 || no >= self->num_matches) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_IndexError, no_in));
|
||||
}
|
||||
@@ -86,10 +86,10 @@ STATIC const mp_obj_type_t match_type = {
|
||||
.locals_dict = (mp_obj_t)&match_locals_dict,
|
||||
};
|
||||
|
||||
STATIC void re_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_re_t *self = self_in;
|
||||
print(env, "<re %p>", self);
|
||||
mp_printf(print, "<re %p>", self);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
||||
@@ -135,7 +135,7 @@ STATIC mp_obj_t re_split(uint n_args, const mp_obj_t *args) {
|
||||
|
||||
int maxsplit = 0;
|
||||
if (n_args > 2) {
|
||||
maxsplit = mp_obj_int_get_truncated(args[2]);
|
||||
maxsplit = mp_obj_get_int(args[2]);
|
||||
}
|
||||
|
||||
mp_obj_t retval = mp_obj_new_list(0, NULL);
|
||||
|
||||
@@ -1,163 +1,21 @@
|
||||
FatFs Module Source Files R0.10c (C)ChaN, 2014
|
||||
FatFs Module Source Files R0.11
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
ffconf.h Configuration file for FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
ff.c FatFs module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
option Optional external functions.
|
||||
00readme.txt This file.
|
||||
history.txt Revision history.
|
||||
ffconf.h Configuration file for FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
ff.c FatFs module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
option Optional external functions.
|
||||
|
||||
|
||||
Low level disk I/O module is not included in this archive because the FatFs
|
||||
module is only a generic file system layer and not depend on any specific
|
||||
storage device. You have to provide a low level disk I/O module that written
|
||||
to control your storage device.
|
||||
to control the target storage device.
|
||||
|
||||
|
||||
|
||||
AGREEMENTS
|
||||
|
||||
FatFs module is an open source software to implement FAT file system to
|
||||
small embedded systems. This is a free software and is opened for education,
|
||||
research and commercial developments under license policy of following trems.
|
||||
|
||||
Copyright (C) 2014, ChaN, all right reserved.
|
||||
|
||||
* The FatFs module is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
|
||||
|
||||
|
||||
REVISION HISTORY
|
||||
|
||||
Feb 26, 2006 R0.00 Prototype
|
||||
|
||||
Apr 29, 2006 R0.01 First release.
|
||||
|
||||
Jun 01, 2006 R0.02 Added FAT12.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) patition.
|
||||
|
||||
Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
|
||||
|
||||
Sep 22, 2006 R0.03 Added f_rename.
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
|
||||
Fixed f_mkdir creates incorrect directory on FAT32.
|
||||
|
||||
Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
|
||||
Changed some APIs for multiple drive system.
|
||||
Added f_mkfs. (FatFs)
|
||||
Added _USE_FAT32 option. (Tiny-FatFs)
|
||||
|
||||
Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
|
||||
Fixed an endian sensitive code in f_mkfs. (FatFs)
|
||||
Added a capability of extending the file size to f_lseek.
|
||||
Added minimization level 3.
|
||||
Fixed a problem that can collapse a sector when recreate an
|
||||
existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
|
||||
|
||||
May 05, 2007 R0.04b Added _USE_NTFLAG option.
|
||||
Added FSInfo support.
|
||||
Fixed some problems corresponds to FAT32. (Tiny-FatFs)
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (0 < ofs <= csize) collapses the file object.
|
||||
|
||||
Aug 25, 2007 R0.05 Changed arguments of f_read, f_write.
|
||||
Changed arguments of f_mkfs. (FatFs)
|
||||
Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
|
||||
Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
|
||||
|
||||
Feb 03, 2008 R0.05a Added f_truncate().
|
||||
Added f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs)
|
||||
Added string functions: fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on move to the same or following cluster.
|
||||
|
||||
Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option.
|
||||
Added long file name support.
|
||||
Added multiple code page support.
|
||||
Added re-entrancy for multitask operation.
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size support.
|
||||
|
||||
Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir().
|
||||
Added f_chdrive().
|
||||
Added proper case conversion for extended characters.
|
||||
|
||||
Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
|
||||
Fixed name matching error on the 13 char boundary.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed fname member in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf function.
|
||||
Ignores duplicated directory separators in given path names.
|
||||
|
||||
Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
|
||||
Added f_fdisk(). (_MULTI_PARTITION = 2)
|
||||
|
||||
Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16.
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
|
||||
Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL)
|
||||
|
||||
Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
|
||||
|
||||
Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1.
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired.
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions.
|
||||
|
||||
Mar 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN.
|
||||
|
||||
Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel().
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry.
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "usbdisk.h" /* Example: USB drive control */
|
||||
#include "atadrive.h" /* Example: ATA drive control */
|
||||
#include "sdcard.h" /* Example: MMC/SDC contorl */
|
||||
#include "usbdisk.h" /* Example: Header file of existing USB MSD control module */
|
||||
#include "atadrive.h" /* Example: Header file of existing ATA harddisk control module */
|
||||
#include "sdcard.h" /* Example: Header file of existing MMC/SDC contorl module */
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define ATA 0 /* Example: Map ATA drive to drive number 0 */
|
||||
#define MMC 1 /* Example: Map MMC/SD card to drive number 1 */
|
||||
#define USB 2 /* Example: Map USB drive to drive number 2 */
|
||||
#define ATA 0 /* Example: Map ATA harddisk to physical drive 0 */
|
||||
#define MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
|
||||
#define USB 2 /* Example: Map USB MSD to physical drive 2 */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
750
lib/fatfs/ff.c
750
lib/fatfs/ff.c
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,23 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.10c (C)ChaN, 2014
|
||||
/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following terms.
|
||||
/ FatFs module is a free software that opened under license policy of
|
||||
/ following conditions.
|
||||
/
|
||||
/ Copyright (C) 2014, ChaN, all right reserved.
|
||||
/ Copyright (C) 2015, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 80376 /* Revision ID */
|
||||
#define _FATFS 32020 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -36,6 +38,7 @@ typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
// dpgeorge: make the partition config table const
|
||||
extern const PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
@@ -154,11 +157,14 @@ typedef struct {
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
#if _USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
@@ -215,11 +221,13 @@ FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
@@ -239,6 +247,8 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
/ FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FFCONF 80376 /* Revision ID */
|
||||
#define _FFCONF 32020 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes basic writing API functions, f_write(),
|
||||
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
|
||||
/ f_getfree() and optional writing functions as well. */
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some API functions.
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
|
||||
@@ -42,9 +42,13 @@
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read feature and related functions,
|
||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_READONLY need to be set to 0. */
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
@@ -57,8 +61,8 @@
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
/* To enable it, also _FS_TINY need to be set to 1. */
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
@@ -69,32 +73,24 @@
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift_JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 0
|
||||
@@ -163,7 +159,7 @@
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
@@ -200,9 +196,9 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 11
|
||||
#define _NORTC_MDAY 9
|
||||
#define _NORTC_YEAR 2014
|
||||
#define _NORTC_MON 2
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
|
||||
180
lib/fatfs/history.txt
Normal file
180
lib/fatfs/history.txt
Normal file
@@ -0,0 +1,180 @@
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
Prototype.
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
First stable version.
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
@@ -529,12 +529,45 @@ WCHAR ff_wtoupper ( /* Upper converted character */
|
||||
WCHAR chr /* Input character */
|
||||
)
|
||||
{
|
||||
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
|
||||
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
|
||||
int i;
|
||||
// dpgeorge: here we have a space optimised version of the original routine
|
||||
|
||||
static const WCHAR tbl_lower[] = {
|
||||
0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF,
|
||||
0xFF,
|
||||
0x17A, 0x17C, 0x17E, 0x192,
|
||||
0, // sentinel
|
||||
};
|
||||
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
static const WCHAR tbl_upper[] = {
|
||||
0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3,
|
||||
0x178,
|
||||
0x179, 0x17B, 0x17D, 0x191,
|
||||
};
|
||||
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
if ((0x61 <= chr && chr <= 0x7a)
|
||||
|| (0xe0 <= chr && chr <= 0xfe && chr != 0xf7)
|
||||
|| (0x3b1 <= chr && chr <= 0x3ca && chr != 0x3c2)
|
||||
|| (0x430 <= chr && chr <= 0x44f)
|
||||
|| (0xff41 <= chr && chr <= 0xff5a)) {
|
||||
return chr - 0x20;
|
||||
}
|
||||
if ((chr & 1) != 0
|
||||
&& ((0x101 <= chr && chr <= 0x137)
|
||||
|| (0x14b <= chr && chr <= 0x177))) {
|
||||
return chr - 1;
|
||||
}
|
||||
if ((chr & 1) == 0 && 0x13a <= chr && chr <= 0x148) {
|
||||
return chr - 1;
|
||||
}
|
||||
if (0x451 <= chr && chr <= 0x45f && chr != 0x45d) {
|
||||
return chr - 0x50;
|
||||
}
|
||||
if (0x2170 <= chr && chr <= 0x217f) {
|
||||
return chr - 0x10;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "cc949.c"
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#include "cc950.c"
|
||||
#else /* Small character-set */
|
||||
#else /* Single Byte Character-Set */
|
||||
#include "ccsbcs.c"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "std.h"
|
||||
#include <string.h>
|
||||
|
||||
#define likely(x) __builtin_expect((x), 1)
|
||||
|
||||
@@ -102,16 +102,30 @@ void *memset(void *s, int c, size_t n) {
|
||||
return s;
|
||||
}
|
||||
|
||||
int memcmp(const char *s1, const char *s2, size_t n) {
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
const uint8_t *s1_8 = s1;
|
||||
const uint8_t *s2_8 = s2;
|
||||
while (n--) {
|
||||
char c1 = *s1++;
|
||||
char c2 = *s2++;
|
||||
char c1 = *s1_8++;
|
||||
char c2 = *s2_8++;
|
||||
if (c1 < c2) return -1;
|
||||
else if (c1 > c2) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memchr(const void *s, int c, size_t n) {
|
||||
if (n != 0) {
|
||||
const unsigned char *p = s;
|
||||
|
||||
do {
|
||||
if (*p++ == c)
|
||||
return ((void *)(p - 1));
|
||||
} while (--n != 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t strlen(const char *str) {
|
||||
int len = 0;
|
||||
for (const char *s = str; *s; s++) {
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/repl.h"
|
||||
#include "readline.h"
|
||||
#ifdef MICROPY_HAL_H
|
||||
#include MICROPY_HAL_H
|
||||
@@ -85,6 +86,7 @@ typedef struct _readline_t {
|
||||
int hist_cur;
|
||||
int cursor_pos;
|
||||
char escape_seq_buf[1];
|
||||
const char *prompt;
|
||||
} readline_t;
|
||||
|
||||
STATIC readline_t rl;
|
||||
@@ -133,6 +135,28 @@ int readline_process_char(int c) {
|
||||
redraw_step_back = 1;
|
||||
redraw_from_cursor = true;
|
||||
}
|
||||
#if MICROPY_HELPER_REPL
|
||||
} else if (c == 9) {
|
||||
// tab magic
|
||||
const char *compl_str;
|
||||
mp_uint_t compl_len = mp_repl_autocomplete(rl.line->buf + rl.orig_line_len, rl.cursor_pos - rl.orig_line_len, &mp_plat_print, &compl_str);
|
||||
if (compl_len == 0) {
|
||||
// no match
|
||||
} else if (compl_len == (mp_uint_t)(-1)) {
|
||||
// many matches
|
||||
mp_hal_stdout_tx_str(rl.prompt);
|
||||
mp_hal_stdout_tx_strn(rl.line->buf + rl.orig_line_len, rl.cursor_pos - rl.orig_line_len);
|
||||
redraw_from_cursor = true;
|
||||
} else {
|
||||
// one match
|
||||
for (int i = 0; i < compl_len; ++i) {
|
||||
vstr_ins_byte(rl.line, rl.cursor_pos + i, *compl_str++);
|
||||
}
|
||||
// set redraw parameters
|
||||
redraw_from_cursor = true;
|
||||
redraw_step_forward = compl_len;
|
||||
}
|
||||
#endif
|
||||
} else if (32 <= c && c <= 126) {
|
||||
// printable character
|
||||
vstr_ins_char(rl.line, rl.cursor_pos, c);
|
||||
@@ -260,23 +284,26 @@ end_key:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void readline_note_newline(void) {
|
||||
void readline_note_newline(const char *prompt) {
|
||||
rl.orig_line_len = rl.line->len;
|
||||
rl.cursor_pos = rl.orig_line_len;
|
||||
rl.prompt = prompt;
|
||||
mp_hal_stdout_tx_str(prompt);
|
||||
}
|
||||
|
||||
void readline_init(vstr_t *line) {
|
||||
void readline_init(vstr_t *line, const char *prompt) {
|
||||
rl.line = line;
|
||||
rl.orig_line_len = line->len;
|
||||
rl.escape_seq = ESEQ_NONE;
|
||||
rl.escape_seq_buf[0] = 0;
|
||||
rl.hist_cur = -1;
|
||||
rl.cursor_pos = rl.orig_line_len;
|
||||
rl.prompt = prompt;
|
||||
mp_hal_stdout_tx_str(prompt);
|
||||
}
|
||||
|
||||
int readline(vstr_t *line, const char *prompt) {
|
||||
mp_hal_stdout_tx_str(prompt);
|
||||
readline_init(line);
|
||||
readline_init(line, prompt);
|
||||
for (;;) {
|
||||
int c = mp_hal_stdin_rx_chr();
|
||||
int r = readline_process_char(c);
|
||||
|
||||
@@ -33,6 +33,6 @@
|
||||
void readline_init0(void);
|
||||
int readline(vstr_t *line, const char *prompt);
|
||||
|
||||
void readline_init(vstr_t *line);
|
||||
void readline_note_newline(void);
|
||||
void readline_init(vstr_t *line, const char *prompt);
|
||||
void readline_note_newline(const char *prompt);
|
||||
int readline_process_char(int c);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user