Compare commits
No commits in common. "cross" and "v1.8.4" have entirely different histories.
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -10,11 +10,11 @@
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.dxf binary
|
||||
*.mpy 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
|
||||
@ -28,3 +28,4 @@ cc3200/hal/des.c -text
|
||||
cc3200/hal/i2s.c -text
|
||||
cc3200/hal/i2s.h -text
|
||||
cc3200/version.h -text
|
||||
lib/fatfs/** -text
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@ -9,7 +9,7 @@
|
||||
*.dis
|
||||
*.exe
|
||||
|
||||
# Packages
|
||||
# Packages
|
||||
############
|
||||
|
||||
# Logs and Databases
|
||||
@ -38,7 +38,3 @@ __pycache__/
|
||||
######################
|
||||
GNUmakefile
|
||||
user.props
|
||||
|
||||
# Generated rst files
|
||||
######################
|
||||
genrst/
|
||||
|
||||
22
.travis.yml
22
.travis.yml
@ -3,9 +3,6 @@ dist: trusty
|
||||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
cache:
|
||||
directories:
|
||||
- "${HOME}/persist"
|
||||
|
||||
before_script:
|
||||
# Extra CPython versions
|
||||
@ -15,7 +12,7 @@ before_script:
|
||||
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
|
||||
- sudo dpkg --add-architecture i386
|
||||
- sudo apt-get update -qq || true
|
||||
- sudo apt-get install -y python3 gcc-multilib pkg-config libffi-dev libffi-dev:i386 qemu-system gcc-mingw-w64
|
||||
- sudo apt-get install -y python3 gcc-multilib pkg-config libffi-dev libffi-dev:i386 qemu-system mingw32
|
||||
- sudo apt-get install -y --force-yes gcc-arm-none-eabi
|
||||
# For teensy build
|
||||
- sudo apt-get install realpath
|
||||
@ -27,25 +24,19 @@ before_script:
|
||||
|
||||
script:
|
||||
- make -C mpy-cross
|
||||
- make -C minimal CROSS=1 build/firmware.bin
|
||||
- ls -l minimal/build/firmware.bin
|
||||
- tools/check_code_size.sh
|
||||
- mkdir -p ${HOME}/persist
|
||||
# Save new firmware for reference, but only if building a main branch, not a pull request
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cp minimal/build/firmware.bin ${HOME}/persist/; fi'
|
||||
- make -C minimal test
|
||||
- make -C unix deplibs
|
||||
- make -C unix
|
||||
- make -C unix nanbox
|
||||
- make -C bare-arm
|
||||
- make -C qemu-arm test
|
||||
- make -C stmhal
|
||||
- make -C stmhal BOARD=PYBV11 MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
|
||||
- make -C stmhal BOARD=STM32F769DISC
|
||||
- make -C stmhal BOARD=STM32L476DISC
|
||||
- make -C stmhal -B MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
|
||||
- make -C stmhal BOARD=STM32F4DISC
|
||||
- make -C teensy
|
||||
- make -C cc3200 BTARGET=application BTYPE=release
|
||||
- make -C cc3200 BTARGET=bootloader BTYPE=release
|
||||
- make -C windows CROSS_COMPILE=i686-w64-mingw32-
|
||||
- make -C windows CROSS_COMPILE=i586-mingw32msvc-
|
||||
|
||||
# run tests without coverage info
|
||||
#- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests)
|
||||
@ -56,9 +47,8 @@ script:
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests -d thread)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests --emit native)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests --via-mpy -d basics float)
|
||||
|
||||
# run coveralls coverage analysis (try to, even if some builds/tests failed)
|
||||
after_success:
|
||||
- (cd unix && coveralls --root .. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod)
|
||||
|
||||
after_failure:
|
||||
|
||||
@ -1448,7 +1448,7 @@ indicating that they also supported the first campaign.
|
||||
* 902 B Stevens
|
||||
903 Cptnslick, US
|
||||
904 janlj@me.com
|
||||
905 Fabricio Biazzotto
|
||||
905 São Caetano do Sul, SP, Brazil
|
||||
906 Lenz Hirsch
|
||||
907 SerSher, RU
|
||||
908 Florian, DE
|
||||
|
||||
@ -24,28 +24,7 @@ a change in a detail, if needed. Any change beyond 5 lines would likely
|
||||
require such detailed description.
|
||||
|
||||
To get good practical examples of good commits and their messages, browse
|
||||
the `git log` of the project.
|
||||
|
||||
MicroPython doesn't require explicit sign-off for patches ("Signed-off-by"
|
||||
lines and similar). Instead, the commit message, and your name and email
|
||||
address on it construes your sign-off of the following:
|
||||
|
||||
* That you wrote the change yourself, or took it from a project with
|
||||
a compatible license (in the latter case the commit message, and possibly
|
||||
source code should provide reference where the implementation was taken
|
||||
from and give credit to the original author, as required by the license).
|
||||
* That you are allowed to release these changes to an open-source project
|
||||
(for example, changes done during paid work for a third party may require
|
||||
explicit approval from that third party).
|
||||
* That you (or your employer) agree to release the changes under
|
||||
MicroPython's license, which is the MIT license. Note that you retain
|
||||
copyright for your changes (for smaller changes, the commit message
|
||||
conveys your copyright; if you make significant changes to a particular
|
||||
source module, you're welcome to add your name to the file header).
|
||||
* Your signature for all of the above, which is the 'Author' line in
|
||||
the commit message, and which should include your full real name and
|
||||
a valid and active email address by which you can be contacted in the
|
||||
foreseeable future.
|
||||
thry the `git log` of the project.
|
||||
|
||||
Python code conventions
|
||||
=======================
|
||||
@ -73,7 +52,7 @@ White space:
|
||||
keyword and the opening parenthesis.
|
||||
- Put 1 space after a comma, and 1 space around operators.
|
||||
|
||||
Braces:
|
||||
Braces:
|
||||
- Use braces for all blocks, even no-line and single-line pieces of
|
||||
code.
|
||||
- Put opening braces on the end of the line it belongs to, not on
|
||||
@ -135,76 +114,3 @@ Type declarations:
|
||||
int member;
|
||||
void *data;
|
||||
} my_struct_t;
|
||||
|
||||
Documentation conventions
|
||||
=========================
|
||||
|
||||
MicroPython generally follows CPython in documentation process and
|
||||
conventions. reStructuredText syntax is used for the documention.
|
||||
|
||||
Specific conventions/suggestions:
|
||||
|
||||
* Use `*` markup to refer to arguments of a function, e.g.:
|
||||
|
||||
```
|
||||
.. method:: poll.unregister(obj)
|
||||
|
||||
Unregister *obj* from polling.
|
||||
```
|
||||
|
||||
* Use following syntax for cross-references/cross-links:
|
||||
|
||||
```
|
||||
:func:`foo` - function foo in current module
|
||||
:func:`module1.foo` - function foo in module "module1"
|
||||
(similarly for other referent types)
|
||||
:class:`Foo` - class Foo
|
||||
:meth:`Class.method1` - method1 in Class
|
||||
:meth:`~Class.method1` - method1 in Class, but rendered just as "method1()",
|
||||
not "Class.method1()"
|
||||
:meth:`title <method1>` - reference method1, but render as "title" (use only
|
||||
if really needed)
|
||||
:mod:`module1` - module module1
|
||||
|
||||
`symbol` - generic xref syntax which can replace any of the above in case
|
||||
the xref is unambiguous. If there's ambiguity, there will be a warning
|
||||
during docs generation, which need to be fixed using one of the syntaxes
|
||||
above
|
||||
```
|
||||
|
||||
* Cross-referencing arbitrary locations
|
||||
~~~
|
||||
.. _xref_target:
|
||||
|
||||
Normal non-indented text.
|
||||
|
||||
This is :ref:`reference <xref_target>`.
|
||||
|
||||
(If xref target is followed by section title, can be just
|
||||
:ref:`xref_target`).
|
||||
~~~
|
||||
|
||||
* Linking to external URL:
|
||||
```
|
||||
`link text <http://foo.com/...>`_
|
||||
```
|
||||
|
||||
* Referencing builtin singleton objects:
|
||||
```
|
||||
``None``, ``True``, ``False``
|
||||
```
|
||||
|
||||
* Use following syntax to create common description for more than one element:
|
||||
~~~
|
||||
.. function:: foo(x)
|
||||
bar(y)
|
||||
|
||||
Description common to foo() and bar().
|
||||
~~~
|
||||
|
||||
|
||||
More detailed guides and quickrefs:
|
||||
|
||||
* http://www.sphinx-doc.org/en/stable/rest.html
|
||||
* http://www.sphinx-doc.org/en/stable/markup/inline.html
|
||||
* http://docutils.sourceforge.net/docs/user/rst/quickref.html
|
||||
|
||||
42
README.md
42
README.md
@ -1,4 +1,12 @@
|
||||
[](https://travis-ci.org/micropython/micropython) [](https://coveralls.io/r/micropython/micropython?branch=master)
|
||||
[![Build Status][travis-img]][travis-repo] [![Coverage Status][coveralls-img]][coveralls-repo] [![Issue Stats][istats-pr-img]][istats-pr-repo] [![Issue Stats][istats-issue-img]][istats-issue-repo]
|
||||
[travis-img]: https://travis-ci.org/micropython/micropython.png?branch=master
|
||||
[travis-repo]: https://travis-ci.org/micropython/micropython
|
||||
[coveralls-img]: https://coveralls.io/repos/micropython/micropython/badge.png?branch=master
|
||||
[coveralls-repo]: https://coveralls.io/r/micropython/micropython?branch=master
|
||||
[istats-pr-img]: http://issuestats.com/github/micropython/micropython/badge/pr
|
||||
[istats-pr-repo]: http://issuestats.com/github/micropython/micropython
|
||||
[istats-issue-img]: http://issuestats.com/github/micropython/micropython/badge/issue
|
||||
[istats-issue-repo]: http://issuestats.com/github/micropython/micropython
|
||||
|
||||
The MicroPython project
|
||||
=======================
|
||||
@ -14,35 +22,26 @@ WARNING: this project is in beta stage and is subject to changes of the
|
||||
code-base, including project-wide name changes and API changes.
|
||||
|
||||
MicroPython implements the entire Python 3.4 syntax (including exceptions,
|
||||
`with`, `yield from`, etc., and additionally `async`/`await` keywords from
|
||||
Python 3.5). The following core datatypes are provided: `str` (including
|
||||
basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`,
|
||||
`frozenset`, `array.array`, `collections.namedtuple`, classes and instances.
|
||||
Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have
|
||||
support for `_thread` module (multithreading). Note that only a subset of
|
||||
Python 3 functionality is implemented for the data types and modules.
|
||||
"with", "yield from", etc., and additionally "async" keyword from Python 3.5).
|
||||
The following core datatypes are provided: str (including basic Unicode
|
||||
support), bytes, bytearray, tuple, list, dict, set, frozenset, array.array,
|
||||
collections.namedtuple, classes and instances. Builtin modules include sys,
|
||||
time, and struct. Note that only subset of Python 3.4 functionality
|
||||
implemented for the data types and modules.
|
||||
|
||||
MicroPython can execute scripts in textual source form or from precompiled
|
||||
bytecode, in both cases either from an on-device filesystem or "frozen" into
|
||||
the MicroPython executable.
|
||||
|
||||
See the repository http://github.com/micropython/pyboard for the MicroPython
|
||||
board (PyBoard), the officially supported reference electronic circuit board.
|
||||
See the repository www.github.com/micropython/pyboard for the Micro
|
||||
Python board, the officially supported reference electronic circuit board.
|
||||
|
||||
Major components in this repository:
|
||||
- py/ -- the core Python implementation, including compiler, runtime, and
|
||||
core library.
|
||||
- mpy-cross/ -- the MicroPython cross-compiler which is used to turn scripts
|
||||
into precompiled bytecode.
|
||||
- unix/ -- a version of MicroPython that runs on Unix.
|
||||
- stmhal/ -- a version of MicroPython that runs on the PyBoard and similar
|
||||
STM32 boards (using ST's Cube HAL drivers).
|
||||
- stmhal/ -- a version of MicroPython that runs on the MicroPython board
|
||||
with an STM32F405RG (using ST's Cube HAL drivers).
|
||||
- minimal/ -- a minimal MicroPython port. Start with this if you want
|
||||
to port MicroPython to another microcontroller.
|
||||
- tests/ -- test framework and test scripts.
|
||||
- docs/ -- user documentation in Sphinx reStructuredText format. Rendered
|
||||
HTML documentation is available at http://docs.micropython.org (be sure
|
||||
to select needed board/port at the bottom left corner).
|
||||
- docs/ -- user documentation in Sphinx reStructuredText format.
|
||||
|
||||
Additional components:
|
||||
- bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used
|
||||
@ -52,7 +51,6 @@ Additional components:
|
||||
- pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers.
|
||||
- cc3200/ -- a version of MicroPython that runs on the CC3200 from TI.
|
||||
- esp8266/ -- an experimental port for ESP8266 WiFi modules.
|
||||
- extmod/ -- additional (non-core) modules implemented in C.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
- examples/ -- a few example Python scripts.
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ INC += -I..
|
||||
INC += -I$(BUILD)
|
||||
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
|
||||
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
|
||||
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
|
||||
@ -6,12 +6,15 @@
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||
@ -32,7 +35,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
@ -45,7 +48,6 @@ mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs)
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
|
||||
@ -46,6 +46,8 @@
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define BYTES_PER_WORD (4)
|
||||
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
||||
|
||||
#define UINT_FMT "%lu"
|
||||
@ -59,6 +61,7 @@ typedef long mp_off_t;
|
||||
#define MP_PLAT_PRINT_STRN(str, len) (void)0
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ MEMORY
|
||||
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
|
||||
}
|
||||
|
||||
|
||||
/* top end of the stack */
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
|
||||
@ -30,7 +30,7 @@ SECTIONS
|
||||
|
||||
. = ALIGN(4);
|
||||
} >FLASH_ISR
|
||||
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
@ -46,7 +46,7 @@ SECTIONS
|
||||
_etext = .; /* define a global symbol at end of code */
|
||||
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
|
||||
} >FLASH_TEXT
|
||||
|
||||
|
||||
/*
|
||||
.ARM.extab :
|
||||
{
|
||||
@ -60,7 +60,7 @@ SECTIONS
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
*/
|
||||
|
||||
|
||||
/* This is the initialized data section
|
||||
The program executes knowing that the data is in the RAM
|
||||
but the loader puts the initial values in the FLASH (inidata).
|
||||
@ -76,7 +76,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
|
||||
} >RAM
|
||||
|
||||
|
||||
/* Uninitialized data section */
|
||||
.bss :
|
||||
{
|
||||
|
||||
@ -8,9 +8,6 @@ endif
|
||||
# Make 'release' the default build type
|
||||
BTYPE ?= release
|
||||
|
||||
# Port for flashing firmware
|
||||
PORT ?= /dev/ttyUSB1
|
||||
|
||||
# If the build directory is not given, make it reflect the board name.
|
||||
BUILD ?= build/$(BOARD)/$(BTYPE)
|
||||
|
||||
@ -20,16 +17,12 @@ include ../py/mkenv.mk
|
||||
CROSS_COMPILE ?= arm-none-eabi-
|
||||
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -march=armv7e-m -mabi=aapcs -mcpu=cortex-m4 -msoft-float -mfloat-abi=soft -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS = -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os
|
||||
CFLAGS = -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os
|
||||
CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access
|
||||
CFLAGS += -Iboards/$(BOARD)
|
||||
CFLAGS += $(CFLAGS_MOD)
|
||||
|
||||
LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map
|
||||
|
||||
FLASH_SIZE_WIPY = 2M
|
||||
FLASH_SIZE_LAUNCHXL = 1M
|
||||
|
||||
ifeq ($(BTARGET), application)
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
|
||||
@ -46,18 +39,3 @@ endif
|
||||
|
||||
# always include MicroPython make rules
|
||||
include ../py/mkrules.mk
|
||||
|
||||
erase:
|
||||
cc3200tool -p $(PORT) format_flash --size $(FLASH_SIZE_$(BOARD))
|
||||
|
||||
deploy:
|
||||
cc3200tool -p $(PORT) \
|
||||
write_file bootmgr/build/$(BOARD)/$(BTYPE)/bootloader.bin /sys/mcuimg.bin \
|
||||
write_file build/$(BOARD)/$(BTYPE)/mcuimg.bin /sys/factimg.bin
|
||||
|
||||
# Files *.ucf and *ucf.signed.bin come from CC3200SDK-SERVICEPACK
|
||||
# package from http://www.ti.com/tool/cc3200sdk
|
||||
servicepack:
|
||||
cc3200tool -p $(PORT) \
|
||||
write_file --file-size=0x20000 --signature ota_1.0.1.6-2.7.0.0.ucf.signed.bin \
|
||||
ota_1.0.1.6-2.7.0.0.ucf /sys/servicepack.ucf
|
||||
|
||||
135
cc3200/README.md
135
cc3200/README.md
@ -1,66 +1,36 @@
|
||||
MicroPython port to CC3200 WiFi SoC
|
||||
===================================
|
||||
# Build Instructions for the CC3200
|
||||
|
||||
This is a MicroPython port to Texas Instruments CC3200 WiFi SoC (ARM Cortex-M4
|
||||
architecture). This port supports 2 boards: WiPy and TI CC3200-LAUNCHXL.
|
||||
Currently the CC3200 port of MicroPython builds under Linux and OSX **but not under Windows**.
|
||||
|
||||
## Build Instructions for the CC3200
|
||||
The tool chain required for the build can be found at <https://launchpad.net/gcc-arm-embedded>.
|
||||
|
||||
Currently the CC3200 port of MicroPython builds under Linux and OSX,
|
||||
but not under Windows.
|
||||
In order to download the image to the CC3200 you will need the CCS_Uniflash tool from TI, which at this
|
||||
moment is only available for Windows, so, you need Linux/OSX to build and Windows to flash the image.
|
||||
|
||||
The toolchain required for the build can be found at
|
||||
<https://launchpad.net/gcc-arm-embedded>.
|
||||
|
||||
In order to flash the image to the CC3200 you will need the
|
||||
[cc3200tool](https://github.com/ALLTERCO/cc3200tool). An alternative is
|
||||
to use CCS_Uniflash tool from TI, which works only under Windows, and all
|
||||
support is provided by TI itself.
|
||||
|
||||
Building the bootloader:
|
||||
## To build an image suitable for debugging:
|
||||
|
||||
In order to debug the port specific code, optimizations need to be disabled on the
|
||||
port file (check the Makefile for specific details). You can use CCS from TI.
|
||||
Use the CC3200.ccxml file supplied with this distribution for the debuuger configuration.
|
||||
```bash
|
||||
make BTARGET=application BTYPE=debug BOARD=LAUNCHXL
|
||||
```
|
||||
## To build an image suitable to be flashed to the device:
|
||||
```bash
|
||||
make BTARGET=application BTYPE=release BOARD=LAUNCHXL
|
||||
```
|
||||
## Building the bootloader
|
||||
```bash
|
||||
make BTARGET=bootloader BTYPE=release BOARD=LAUNCHXL
|
||||
```
|
||||
|
||||
Building the "release" image:
|
||||
|
||||
```
|
||||
make BTARGET=application BTYPE=release BOARD=LAUNCHXL
|
||||
```
|
||||
|
||||
To build an image suitable for debugging:
|
||||
|
||||
In order to debug the port specific code, optimizations need to be disabled on the
|
||||
port file (check the Makefile for specific details). You can use CCS from TI.
|
||||
Use the CC3200.ccxml file supplied with this distribution for the debuuger configuration.
|
||||
|
||||
```
|
||||
make BTARGET=application BTYPE=debug BOARD=LAUNCHXL
|
||||
```
|
||||
|
||||
## Flashing the CC3200-LAUNCHXL
|
||||
|
||||
Note that WiPy comes factory programmed with a default version of MicroPython,
|
||||
it cannot be programmed via serial, and can be upgraded only with OTA (see
|
||||
below).
|
||||
## Regarding old revisions of the CC3200-LAUNCHXL
|
||||
First silicon (pre-release) revisions of the CC3200 had issues with the ram blocks, and MicroPython cannot run
|
||||
there. Make sure to use a **v4.1 (or higer) LAUNCHXL board** when trying this port, otherwise it won't work.
|
||||
|
||||
## Flashing the CC3200
|
||||
- Make sure that you have built both the *bootloader* and the *application* in **release** mode.
|
||||
- Make sure the SOP2 jumper is in position.
|
||||
- Make sure you Linux system recognized the board and created `ttyUSB*`
|
||||
devices (see below for configuration of `ftdi_sio` driver).
|
||||
- Run "make erase" and immediately press Reset button on the device.
|
||||
- Wait few seconds.
|
||||
- Run "make deploy" and immediately press Reset button on the device.
|
||||
- You are recommended to install the latest vendor WiFi firmware
|
||||
servicepack from http://www.ti.com/tool/cc3200sdk. Download
|
||||
CC3200SDK-SERVICEPACK package, install it, and locate `ota_*.ucf`
|
||||
and `ota_*.ucf.signed.bin` files. Copy them to the port's directory
|
||||
and run "make servicepack", with immediate press of Reset button.
|
||||
- Remove the SOP2 jumper and reset the board.
|
||||
|
||||
Flashing process using TI Uniflash:
|
||||
|
||||
- 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, 2MB in case of the WiPy, leave the rest unchecked).
|
||||
- Mark the following files for erasing: `/cert/ca.pem`, `/cert/client.pem`, `/cert/private.key` and `/tmp/pac.bin`.
|
||||
@ -70,30 +40,26 @@ Flashing process using TI Uniflash:
|
||||
- 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.
|
||||
|
||||
## Updating the board to with new software version
|
||||
- Make sure the board is running and connected to the same network as the computer.
|
||||
|
||||
```bash
|
||||
make BTARGET=application BTYPE=release BOARD=LAUNCHXL WIPY_IP=192.168.1.1 WIPY_USER=micro WIPY_PWD=python deploy
|
||||
```
|
||||
|
||||
If `WIPY_IP`, `WIPY_USER` or `WIPY_PWD` are omitted the default values (the ones shown above) will be used.
|
||||
|
||||
## Playing with MicroPython and the CC3200:
|
||||
|
||||
Once the software is running, you have two options to access the MicroPython REPL:
|
||||
|
||||
- Through telnet.
|
||||
- Through telnet.
|
||||
* 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"**
|
||||
|
||||
- Through UART (serial).
|
||||
* This is enabled by default in the standard configuration, for UART0 (speed 115200).
|
||||
* For CC3200-LAUNCHXL, you will need to configure Linux `ftdi_sio` driver as described
|
||||
in the [blog post](http://www.achanceofbrainshowers.com/blog/tech/2014/8/19/cc3200-development-under-linux/).
|
||||
After that, connecting a board will create two `/dev/ttyUSB*` devices, a serial
|
||||
console is available on the 2nd one (usually `/dev/ttyUSB1`).
|
||||
* WiPy doesn't have onboard USB-UART converter, so you will need an external one,
|
||||
connected to GPIO01 (Tx) and GPIO02 (Rx).
|
||||
* Usage of UART port for REPL is controlled by MICROPY_STDIO_UART setting (and
|
||||
is done at the high level, using a suitable call to `os.dupterm()` function
|
||||
in boot.py, so you can override it at runtime regardless of MICROPY_STDIO_UART
|
||||
setting).
|
||||
|
||||
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.
|
||||
|
||||
@ -102,19 +68,15 @@ SD cards are also supported, you can connect any SD card and configure the pinou
|
||||
To upload your MicroPython scripts to the FTP server, open your FTP client of choice and connect to:
|
||||
**ftp://192.168.1.1, user = "micro", password = "python"**
|
||||
|
||||
Tested FTP clients are: FileZilla, FireFTP, FireFox, IE and Chrome. Other
|
||||
clients should work as well, but you may need to configure them to use a
|
||||
single connection (this should be the default for any compliant FTP client).
|
||||
I have tested the FTP server with **FileZilla, FireFTP, FireFox, IE and Chrome,** other clients should work as well, but I am
|
||||
not 100% sure of it.
|
||||
|
||||
## Upgrading the firmware Over The Air (OTA)
|
||||
## Upgrading the firmware Over The Air:
|
||||
|
||||
OTA software updates can be performed through the builtin FTP server. After
|
||||
building a new `mcuimg.bin` in release mode, upload it to:
|
||||
`/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.
|
||||
OTA software updates can be performed through the FTP server. After building a new **mcuimg.bin** in release mode, upload it to:
|
||||
`/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
|
||||
@ -122,27 +84,10 @@ import machine
|
||||
machine.reset()
|
||||
```
|
||||
|
||||
There's a script which automates this process from the host side:
|
||||
|
||||
- Make sure the board is running and connected to the same network as the computer.
|
||||
|
||||
```bash
|
||||
make BTARGET=application BTYPE=release BOARD=LAUNCHXL WIPY_IP=192.168.1.1 WIPY_USER=micro WIPY_PWD=python deploy-ota
|
||||
```
|
||||
|
||||
If `WIPY_IP`, `WIPY_USER` or `WIPY_PWD` are omitted the default values (the ones shown above) will be used.
|
||||
|
||||
|
||||
## Notes and known issues
|
||||
|
||||
## Regarding old revisions of the CC3200-LAUNCHXL
|
||||
|
||||
First silicon (pre-release) revisions of the CC3200 had issues with the ram blocks, and MicroPython cannot run
|
||||
there. Make sure to use a **v4.1 (or higher) LAUNCHXL board** when trying this port, otherwise it won't work.
|
||||
|
||||
### Note regarding FileZilla
|
||||
### Note regarding FileZilla:
|
||||
|
||||
Do not use the quick connect button, instead, open the site manager and create a new configuration. In the "General" tab make
|
||||
sure that encryption is set to: "Only use plain FTP (insecure)". In the Transfer Settings tab limit the max number of connections
|
||||
to one, otherwise FileZilla will try to open a second command connection when retrieving and saving files, and for simplicity and
|
||||
to reduce code size, only one command and one data connections are possible.
|
||||
|
||||
|
||||
@ -18,6 +18,10 @@ APP_INC += -Iutil
|
||||
APP_INC += -Ibootmgr
|
||||
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
|
||||
@ -25,6 +29,9 @@ APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
|
||||
APP_FATFS_SRC_C = $(addprefix fatfs/src/,\
|
||||
drivers/sflash_diskio.c \
|
||||
drivers/sd_diskio.c \
|
||||
option/syscall.c \
|
||||
diskio.c \
|
||||
ffconf.c \
|
||||
)
|
||||
|
||||
APP_RTOS_SRC_C = $(addprefix FreeRTOS/Source/,\
|
||||
@ -74,6 +81,7 @@ APP_MISC_SRC_C = $(addprefix misc/,\
|
||||
mpirq.c \
|
||||
mperror.c \
|
||||
mpexception.c \
|
||||
mpsystick.c \
|
||||
)
|
||||
|
||||
APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
@ -90,7 +98,6 @@ APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
pybpin.c \
|
||||
pybi2c.c \
|
||||
pybrtc.c \
|
||||
pybflash.c \
|
||||
pybsd.c \
|
||||
pybsleep.c \
|
||||
pybspi.c \
|
||||
@ -136,23 +143,28 @@ APP_MAIN_SRC_C = \
|
||||
main.c \
|
||||
mptask.c \
|
||||
mpthreadport.c \
|
||||
serverstask.c \
|
||||
fatfs_port.c \
|
||||
serverstask.c
|
||||
|
||||
APP_LIB_SRC_C = $(addprefix lib/,\
|
||||
oofatfs/ff.c \
|
||||
oofatfs/option/unicode.c \
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
libc/string0.c \
|
||||
mp-readline/readline.c \
|
||||
netutils/netutils.c \
|
||||
timeutils/timeutils.c \
|
||||
utils/pyexec.c \
|
||||
utils/sys_stdio_mphal.c \
|
||||
utils/pyhelp.c \
|
||||
)
|
||||
|
||||
APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
bufhelper.c \
|
||||
builtin_open.c \
|
||||
import.c \
|
||||
input.c \
|
||||
irq.c \
|
||||
lexerfatfs.c \
|
||||
moduselect.c \
|
||||
pybstdio.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))
|
||||
@ -196,9 +208,9 @@ WIPY_PWD ?= 'python'
|
||||
|
||||
all: $(BUILD)/mcuimg.bin
|
||||
|
||||
.PHONY: deploy-ota
|
||||
.PHONY: deploy
|
||||
|
||||
deploy-ota: $(BUILD)/mcuimg.bin
|
||||
deploy: $(BUILD)/mcuimg.bin
|
||||
$(ECHO) "Writing $< to the board"
|
||||
$(Q)$(PYTHON) $(UPDATE_WIPY) --verify --ip $(WIPY_IP) --user $(WIPY_USER) --password $(WIPY_PWD) --file $<
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
#define MICROPY_HW_ANTENNA_DIVERSITY (0)
|
||||
|
||||
#define MICROPY_STDIO_UART 1
|
||||
#define MICROPY_STDIO_UART 0
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
|
||||
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA1
|
||||
|
||||
@ -32,9 +32,6 @@
|
||||
|
||||
#define MICROPY_HW_ANTENNA_DIVERSITY (1)
|
||||
|
||||
#define MICROPY_STDIO_UART 1
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
|
||||
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SYS_LED_PORT GPIOA3_BASE
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_BOOTMGR_BOOTMGR_H
|
||||
#define MICROPY_INCLUDED_CC3200_BOOTMGR_BOOTMGR_H
|
||||
|
||||
#ifndef __BOOTMGR_H__
|
||||
#define __BOOTMGR_H__
|
||||
|
||||
//****************************************************************************
|
||||
//
|
||||
@ -65,4 +66,4 @@ extern void Run(unsigned long);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_BOOTMGR_BOOTMGR_H
|
||||
#endif //__BOOTMGR_H__
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_BOOTMGR_FLC_H
|
||||
#define MICROPY_INCLUDED_CC3200_BOOTMGR_FLC_H
|
||||
|
||||
#ifndef __FLC_H__
|
||||
#define __FLC_H__
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@ -92,4 +93,4 @@ typedef struct _sBootInfo_t
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_BOOTMGR_FLC_H
|
||||
#endif /* __FLC_H__ */
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "hw_ints.h"
|
||||
|
||||
209
cc3200/fatfs/src/diskio.c
Normal file
209
cc3200/fatfs/src/diskio.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control modules to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "lib/fatfs/ff.h"
|
||||
#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
|
||||
#include "sflash_diskio.h" /* Serial flash disk IO API */
|
||||
#include "sd_diskio.h" /* SDCARD disk IO API */
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "pybrtc.h"
|
||||
#include "timeutils.h"
|
||||
#include "pybsd.h"
|
||||
#include "moduos.h"
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
return sflash_disk_status();
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||
return STA_PROTECT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
if (RES_OK != sflash_disk_init()) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||
return STA_PROTECT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
return sflash_disk_read(buff, sector, count);
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
return sd_disk_read(buff, sector, count);
|
||||
}
|
||||
mount_obj->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||
mount_obj->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
|
||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->readblocks));
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
return sflash_disk_write(buff, sector, count);
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
return sd_disk_write(buff, sector, count);
|
||||
}
|
||||
mount_obj->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||
mount_obj->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void *)buff);
|
||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->writeblocks));
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
return sflash_disk_flush();
|
||||
case GET_SECTOR_COUNT:
|
||||
*((DWORD*)buff) = SFLASH_SECTOR_COUNT;
|
||||
return RES_OK;
|
||||
case GET_SECTOR_SIZE:
|
||||
*((DWORD*)buff) = SFLASH_SECTOR_SIZE;
|
||||
return RES_OK;
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||
return RES_OK;
|
||||
}
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
if (mount_obj->sync[0] != MP_OBJ_NULL) {
|
||||
mp_call_method_n_kw(0, 0, mount_obj->sync);
|
||||
}
|
||||
return RES_OK;
|
||||
case GET_SECTOR_COUNT:
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
*((DWORD*)buff) = sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512);
|
||||
} else {
|
||||
*((DWORD*)buff) = mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count));
|
||||
}
|
||||
return RES_OK;
|
||||
case GET_SECTOR_SIZE:
|
||||
*((DWORD*)buff) = SD_SECTOR_SIZE; // Sector size is fixed to 512 bytes, as with SD cards
|
||||
return RES_OK;
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !_FS_READONLY && !_FS_NORTC
|
||||
DWORD get_fattime (
|
||||
void
|
||||
)
|
||||
{
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||
|
||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||
((tm.tm_min) << 5) | (tm.tm_sec >> 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -39,12 +39,11 @@
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "hw_types.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "hw_ints.h"
|
||||
#include "rom_map.h"
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "sdhost.h"
|
||||
#include "pin.h"
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "simplelink.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "debug.h"
|
||||
#include "modnetwork.h"
|
||||
|
||||
93
cc3200/fatfs/src/ffconf.c
Normal file
93
cc3200/fatfs/src/ffconf.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "lib/fatfs/ff.h"
|
||||
#include "lib/fatfs/ffconf.h"
|
||||
#include "lib/fatfs/diskio.h"
|
||||
#include "moduos.h"
|
||||
|
||||
#if _FS_RPATH
|
||||
extern BYTE ff_CurrVol;
|
||||
#endif
|
||||
|
||||
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
|
||||
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
|
||||
if ((*path)[mount_point_len] == '/') {
|
||||
*path += mount_point_len;
|
||||
return true;
|
||||
} else if ((*path)[mount_point_len] == '\0') {
|
||||
*path = "/";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// "path" is the path to lookup; will advance this pointer beyond the volume name.
|
||||
// Returns logical drive number (-1 means invalid path).
|
||||
int ff_get_ldnumber (const TCHAR **path) {
|
||||
if (!(*path)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (**path != '/') {
|
||||
#if _FS_RPATH
|
||||
return ff_CurrVol;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (check_path(path, "/flash", 6)) {
|
||||
return PD_FLASH;
|
||||
}
|
||||
else {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (check_path(path, mount_obj->path, mount_obj->pathlen)) {
|
||||
return mount_obj->vol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ff_get_volname(BYTE vol, TCHAR **dest) {
|
||||
if (vol == PD_FLASH) {
|
||||
memcpy(*dest, "/flash", 6);
|
||||
*dest += 6;
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(vol))) {
|
||||
memcpy(*dest, mount_obj->path, mount_obj->pathlen);
|
||||
*dest += mount_obj->pathlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
150
cc3200/fatfs/src/option/syscall.c
Normal file
150
cc3200/fatfs/src/option/syscall.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample code of OS dependent controls for FatFs */
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
#if _FS_REENTRANT
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
|
||||
BYTE vol, /* Corresponding logical drive being processed */
|
||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
//
|
||||
// *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
||||
// ret = (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
|
||||
// ret = 1; /* The initial value of the semaphore must be 1. */
|
||||
|
||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
vSemaphoreCreateBinary( (*sobj) ); /* FreeRTOS */
|
||||
ret = (int)(*sobj != NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj function. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
|
||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
// ret = CloseHandle(sobj); /* Win32 */
|
||||
|
||||
// ret = 1; /* uITRON (nothing to do) */
|
||||
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
vSemaphoreDelete(sobj); /* FreeRTOS */
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||
_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
||||
|
||||
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
|
||||
|
||||
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
// ReleaseMutex(sobj); /* Win32 */
|
||||
|
||||
// sig_sem(sobj); /* uITRON */
|
||||
|
||||
// OSMutexPost(sobj); /* uC/OS-II */
|
||||
|
||||
xSemaphoreGive(sobj); /* FreeRTOS */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||
*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return pvPortMalloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
vPortFree(mblock); /* Discard the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2017 Damien P. George
|
||||
* Parts of this file are (C)ChaN, 2014, from FatFs option/syscall.c
|
||||
*
|
||||
* 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 "lib/oofatfs/ff.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "mods/pybrtc.h"
|
||||
|
||||
#if _FS_REENTRANT
|
||||
// Create a Synchronization Object
|
||||
// This function is called in f_mount() function to create a new
|
||||
// synchronization object, such as semaphore and mutex.
|
||||
// A return of 0 indicates failure, and then f_mount() fails with FR_INT_ERR.
|
||||
int ff_cre_syncobj(FATFS *fatfs, _SYNC_t *sobj) {
|
||||
vSemaphoreCreateBinary((*sobj));
|
||||
return (int)(*sobj != NULL);
|
||||
}
|
||||
|
||||
// Delete a Synchronization Object
|
||||
// This function is called in f_mount() function to delete a synchronization
|
||||
// object that created with ff_cre_syncobj function.
|
||||
// A return of 0 indicates failure, and then f_mount() fails with FR_INT_ERR.
|
||||
int ff_del_syncobj(_SYNC_t sobj) {
|
||||
vSemaphoreDelete(sobj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Request Grant to Access the Volume
|
||||
// This function is called on entering file functions to lock the volume.
|
||||
// When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
int ff_req_grant(_SYNC_t sobj) {
|
||||
return (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE);
|
||||
}
|
||||
|
||||
// Release Grant to Access the Volume
|
||||
// This function is called on leaving file functions to unlock the volume.
|
||||
void ff_rel_grant(_SYNC_t sobj) {
|
||||
xSemaphoreGive(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DWORD get_fattime(void) {
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||
|
||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||
((tm.tm_min) << 5) | (tm.tm_sec >> 1);
|
||||
}
|
||||
163
cc3200/ftp/ftp.c
163
cc3200/ftp/ftp.c
@ -25,14 +25,11 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/obj.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@ -46,9 +43,11 @@
|
||||
#include "modusocket.h"
|
||||
#include "debug.h"
|
||||
#include "serverstask.h"
|
||||
#include "ff.h"
|
||||
#include "fifo.h"
|
||||
#include "socketfifo.h"
|
||||
#include "updater.h"
|
||||
#include "timeutils.h"
|
||||
#include "moduos.h"
|
||||
|
||||
/******************************************************************************
|
||||
@ -116,7 +115,7 @@ typedef struct {
|
||||
uint8_t *dBuffer;
|
||||
uint32_t ctimeout;
|
||||
union {
|
||||
FF_DIR dp;
|
||||
DIR dp;
|
||||
FIL fp;
|
||||
};
|
||||
int16_t lc_sd;
|
||||
@ -193,80 +192,6 @@ static const ftp_month_t ftp_month[] = { { "Jan" }, { "Feb" }, { "Mar" }, { "Apr
|
||||
static SocketFifoElement_t ftp_fifoelements[FTP_SOCKETFIFO_ELEMENTS_MAX];
|
||||
static FIFO_t ftp_socketfifo;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE VFS WRAPPER FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
// These wrapper functions are used so that the FTP server can access the
|
||||
// mounted FATFS devices directly without going through the costly mp_vfs_XXX
|
||||
// functions. The latter may raise exceptions and we would then need to wrap
|
||||
// all calls in an nlr handler. The wrapper functions below assume that there
|
||||
// are only FATFS filesystems mounted.
|
||||
|
||||
STATIC FATFS *lookup_path(const TCHAR **path) {
|
||||
mp_vfs_mount_t *fs = mp_vfs_lookup_path(*path, path);
|
||||
if (fs == MP_VFS_NONE || fs == MP_VFS_ROOT) {
|
||||
return NULL;
|
||||
}
|
||||
// here we assume that the mounted device is FATFS
|
||||
return &((fs_user_mount_t*)MP_OBJ_TO_PTR(fs->obj))->fatfs;
|
||||
}
|
||||
|
||||
STATIC FRESULT f_open_helper(FIL *fp, const TCHAR *path, BYTE mode) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_open(fs, fp, path, mode);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_opendir_helper(FF_DIR *dp, const TCHAR *path) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_opendir(fs, dp, path);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_stat_helper(const TCHAR *path, FILINFO *fno) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_stat(fs, path, fno);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_mkdir_helper(const TCHAR *path) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_mkdir(fs, path);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_unlink_helper(const TCHAR *path) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_unlink(fs, path);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_rename_helper(const TCHAR *path_old, const TCHAR *path_new) {
|
||||
FATFS *fs_old = lookup_path(&path_old);
|
||||
if (fs_old == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
FATFS *fs_new = lookup_path(&path_new);
|
||||
if (fs_new == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
if (fs_old != fs_new) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_rename(fs_new, path_old, path_new);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@ -285,7 +210,7 @@ static void ftp_close_cmd_data (void);
|
||||
static ftp_cmd_index_t ftp_pop_command (char **str);
|
||||
static void ftp_pop_param (char **str, char *param);
|
||||
static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno);
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name);
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name);
|
||||
static bool ftp_open_file (const char *path, int mode);
|
||||
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
|
||||
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
|
||||
@ -335,7 +260,7 @@ void ftp_run (void) {
|
||||
ftp_data.loggin.uservalid = false;
|
||||
ftp_data.loggin.passvalid = false;
|
||||
strcpy (ftp_path, "/");
|
||||
ftp_send_reply (220, "MicroPython FTP Server");
|
||||
ftp_send_reply (220, "Micropython FTP Server");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -499,12 +424,12 @@ static void ftp_wait_for_enabled (void) {
|
||||
|
||||
static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||
SlSockNonblocking_t nonBlockingOption;
|
||||
SlSockAddrIn_t sServerAddress;
|
||||
sockaddr_in sServerAddress;
|
||||
_i16 _sd;
|
||||
_i16 result;
|
||||
|
||||
// Open a socket for ftp data listen
|
||||
ASSERT ((*sd = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_IPPROTO_IP)) > 0);
|
||||
ASSERT ((*sd = sl_Socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) > 0);
|
||||
_sd = *sd;
|
||||
|
||||
if (_sd > 0) {
|
||||
@ -513,12 +438,12 @@ static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||
|
||||
// Enable non-blocking mode
|
||||
nonBlockingOption.NonblockingEnabled = 1;
|
||||
ASSERT ((result = sl_SetSockOpt(_sd, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption))) == SL_SOC_OK);
|
||||
ASSERT ((result = sl_SetSockOpt(_sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption))) == SL_SOC_OK);
|
||||
|
||||
// Bind the socket to a port number
|
||||
sServerAddress.sin_family = SL_AF_INET;
|
||||
sServerAddress.sin_addr.s_addr = SL_INADDR_ANY;
|
||||
sServerAddress.sin_port = sl_Htons(port);
|
||||
sServerAddress.sin_family = AF_INET;
|
||||
sServerAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
sServerAddress.sin_port = htons(port);
|
||||
|
||||
ASSERT ((result |= sl_Bind(_sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress))) == SL_SOC_OK);
|
||||
|
||||
@ -534,7 +459,7 @@ static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||
}
|
||||
|
||||
static ftp_result_t ftp_wait_for_connection (_i16 l_sd, _i16 *n_sd) {
|
||||
SlSockAddrIn_t sClientAddress;
|
||||
sockaddr_in sClientAddress;
|
||||
SlSocklen_t in_addrSize;
|
||||
|
||||
// accepts a connection from a TCP client, if there is any, otherwise returns SL_EAGAIN
|
||||
@ -679,6 +604,10 @@ static void ftp_process_cmd (void) {
|
||||
ftp_result_t result;
|
||||
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
|
||||
@ -705,7 +634,7 @@ static void ftp_process_cmd (void) {
|
||||
fres = FR_NO_PATH;
|
||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||
ftp_open_child (ftp_path, ftp_scratch_buffer);
|
||||
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir_helper (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
||||
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
||||
if (fres == FR_OK) {
|
||||
f_closedir(&ftp_data.dp);
|
||||
}
|
||||
@ -724,7 +653,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_SIZE:
|
||||
{
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||
// send the size
|
||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u", (_u32)fno.fsize);
|
||||
ftp_send_reply(213, (char *)ftp_data.dBuffer);
|
||||
@ -736,7 +665,7 @@ static void ftp_process_cmd (void) {
|
||||
break;
|
||||
case E_FTP_CMD_MDTM:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||
// send the last modified time
|
||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u%02u%02u%02u%02u%02u",
|
||||
1980 + ((fno.fdate >> 9) & 0x7f), (fno.fdate >> 5) & 0x0f,
|
||||
@ -844,7 +773,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_DELE:
|
||||
case E_FTP_CMD_RMD:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_unlink_helper(ftp_path)) {
|
||||
if (FR_OK == f_unlink(ftp_path)) {
|
||||
ftp_send_reply(250, NULL);
|
||||
}
|
||||
else {
|
||||
@ -853,7 +782,7 @@ static void ftp_process_cmd (void) {
|
||||
break;
|
||||
case E_FTP_CMD_MKD:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_mkdir_helper(ftp_path)) {
|
||||
if (FR_OK == f_mkdir(ftp_path)) {
|
||||
ftp_send_reply(250, NULL);
|
||||
}
|
||||
else {
|
||||
@ -862,7 +791,7 @@ static void ftp_process_cmd (void) {
|
||||
break;
|
||||
case E_FTP_CMD_RNFR:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||
ftp_send_reply(350, NULL);
|
||||
// save the current path
|
||||
strcpy ((char *)ftp_data.dBuffer, ftp_path);
|
||||
@ -874,7 +803,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_RNTO:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
// old path was saved in the data buffer
|
||||
if (FR_OK == (fres = f_rename_helper((char *)ftp_data.dBuffer, ftp_path))) {
|
||||
if (FR_OK == (fres = f_rename ((char *)ftp_data.dBuffer, ftp_path))) {
|
||||
ftp_send_reply(250, NULL);
|
||||
}
|
||||
else {
|
||||
@ -931,13 +860,6 @@ static void ftp_close_cmd_data (void) {
|
||||
ftp_close_filesystem_on_error ();
|
||||
}
|
||||
|
||||
static void stoupper (char *str) {
|
||||
while (str && *str != '\0') {
|
||||
*str = (char)unichar_toupper((int)(*str));
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
static ftp_cmd_index_t ftp_pop_command (char **str) {
|
||||
char _cmd[FTP_CMD_SIZE_MAX];
|
||||
ftp_pop_param (str, _cmd);
|
||||
@ -976,16 +898,24 @@ 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, const char *name) {
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t tseconds;
|
||||
char *type = "d";
|
||||
@ -1004,7 +934,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name
|
||||
}
|
||||
|
||||
static bool ftp_open_file (const char *path, int mode) {
|
||||
FRESULT res = f_open_helper(&ftp_data.fp, path, mode);
|
||||
FRESULT res = f_open(&ftp_data.fp, path, mode);
|
||||
if (res != FR_OK) {
|
||||
return false;
|
||||
}
|
||||
@ -1046,7 +976,7 @@ static ftp_result_t ftp_open_dir_for_listing (const char *path) {
|
||||
ftp_data.listroot = true;
|
||||
} else {
|
||||
FRESULT res;
|
||||
res = f_opendir_helper(&ftp_data.dp, path); /* Open the directory */
|
||||
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
return E_FTP_RESULT_FAILED;
|
||||
}
|
||||
@ -1063,6 +993,9 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
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 2 directory items
|
||||
while (listcount < 2) {
|
||||
#else
|
||||
@ -1071,20 +1004,17 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
#endif
|
||||
if (ftp_data.listroot) {
|
||||
// root directory "hack"
|
||||
mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
|
||||
int i = ftp_data.volcount;
|
||||
while (vfs != NULL && i != 0) {
|
||||
vfs = vfs->next;
|
||||
i -= 1;
|
||||
}
|
||||
if (vfs == NULL) {
|
||||
if (0 == ftp_data.volcount) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||
} else if (ftp_data.volcount <= MP_STATE_PORT(mount_obj_list).len) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[(ftp_data.volcount - 1)]));
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), (char *)&mount_obj->path[1]);
|
||||
} else {
|
||||
if (!next) {
|
||||
// no volume found this time, we are done
|
||||
ftp_data.volcount = 0;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), vfs->str + 1);
|
||||
}
|
||||
ftp_data.volcount++;
|
||||
} else {
|
||||
@ -1106,6 +1036,9 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
ftp_close_files();
|
||||
}
|
||||
*listsize = next;
|
||||
#if _USE_LFN
|
||||
mem_Free(fno.lfname);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_FTP_FTP_H
|
||||
#define MICROPY_INCLUDED_CC3200_FTP_FTP_H
|
||||
|
||||
#ifndef FTP_H_
|
||||
#define FTP_H_
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED FUNCTIONS
|
||||
@ -35,4 +36,4 @@ extern void ftp_enable (void);
|
||||
extern void ftp_disable (void);
|
||||
extern void ftp_reset (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_FTP_FTP_H
|
||||
#endif /* FTP_H_ */
|
||||
|
||||
@ -23,8 +23,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_FTP_UPDATER_H
|
||||
#define MICROPY_INCLUDED_CC3200_FTP_UPDATER_H
|
||||
|
||||
|
||||
#ifndef UPDATER_H_
|
||||
#define UPDATER_H_
|
||||
|
||||
extern void updater_pre_init (void);
|
||||
extern bool updater_check_path (void *path);
|
||||
@ -33,4 +35,4 @@ extern bool updater_write (uint8_t *buf, uint32_t len);
|
||||
extern void updater_finnish (void);
|
||||
extern bool updater_verify (uint8_t *rbuff, uint8_t *hasbuff);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_FTP_UPDATER_H
|
||||
#endif /* UPDATER_H_ */
|
||||
|
||||
@ -108,19 +108,6 @@ mp_uint_t mp_hal_ticks_ms(void) {
|
||||
return HAL_tickCount;
|
||||
}
|
||||
|
||||
// The SysTick timer counts down at HAL_FCPU_HZ, so we can use that knowledge
|
||||
// to grab a microsecond counter.
|
||||
mp_uint_t mp_hal_ticks_us(void) {
|
||||
mp_uint_t irq_state = disable_irq();
|
||||
uint32_t counter = SysTickValueGet();
|
||||
uint32_t milliseconds = mp_hal_ticks_ms();
|
||||
enable_irq(irq_state);
|
||||
|
||||
uint32_t load = SysTickPeriodGet();
|
||||
counter = load - counter; // Convert from decrementing to incrementing
|
||||
return (milliseconds * 1000) + ((counter * 1000) / load);
|
||||
}
|
||||
|
||||
void mp_hal_delay_ms(mp_uint_t delay) {
|
||||
// only if we are not within interrupt context and interrupts are enabled
|
||||
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
||||
@ -143,6 +130,10 @@ void mp_hal_delay_ms(mp_uint_t delay) {
|
||||
}
|
||||
}
|
||||
|
||||
NORETURN void mp_hal_raise(int errno) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, mp_obj_new_int(errno)));
|
||||
}
|
||||
|
||||
void mp_hal_set_interrupt_char (int c) {
|
||||
mpexception_set_interrupt_char (c);
|
||||
}
|
||||
@ -224,3 +215,4 @@ static void hal_TickInit (void) {
|
||||
MAP_SysTickEnable();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -24,12 +24,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CC3200_LAUNCHXL_HAL_CC3200_HAL_H_
|
||||
#define CC3200_LAUNCHXL_HAL_CC3200_HAL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "hal/utils.h"
|
||||
#include "hal/systick.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
@ -62,7 +62,7 @@
|
||||
extern void HAL_SystemInit (void);
|
||||
extern void HAL_SystemDeInit (void);
|
||||
extern void HAL_IncrementTick(void);
|
||||
extern NORETURN void mp_hal_raise(int errno);
|
||||
extern void mp_hal_set_interrupt_char (int c);
|
||||
|
||||
#define mp_hal_delay_us(usec) UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec))
|
||||
#define mp_hal_ticks_cpu() (SysTickPeriodGet() - SysTickValueGet())
|
||||
#endif /* CC3200_LAUNCHXL_HAL_CC3200_HAL_H_ */
|
||||
|
||||
@ -89,7 +89,7 @@ int main (void) {
|
||||
#ifndef DEBUG
|
||||
OsiTaskHandle mpTaskHandle;
|
||||
#endif
|
||||
mpTaskHandle = xTaskCreateStatic(TASK_MicroPython, "MicroPy",
|
||||
mpTaskHandle = xTaskCreateStatic(TASK_Micropython, "MicroPy",
|
||||
MICROPY_TASK_STACK_LEN, NULL, MICROPY_TASK_PRIORITY, mpTaskStack, &mpTaskTCB);
|
||||
ASSERT(mpTaskHandle != NULL);
|
||||
|
||||
@ -98,6 +98,13 @@ int main (void) {
|
||||
for ( ; ; );
|
||||
}
|
||||
|
||||
void stoupper (char *str) {
|
||||
while (str && *str != '\0') {
|
||||
*str = (char)toupper((int)(*str));
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
// We need this when configSUPPORT_STATIC_ALLOCATION is enabled
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
StackType_t **ppxIdleTaskStackBuffer,
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MISC_ANTENNA_H
|
||||
#define MICROPY_INCLUDED_CC3200_MISC_ANTENNA_H
|
||||
|
||||
#ifndef _ANTENNA_H_
|
||||
#define _ANTENNA_H_
|
||||
|
||||
typedef enum {
|
||||
ANTENNA_TYPE_INTERNAL = 0,
|
||||
@ -34,4 +35,4 @@ typedef enum {
|
||||
extern void antenna_init0 (void);
|
||||
extern void antenna_select (antenna_type_t antenna_type);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MISC_ANTENNA_H
|
||||
#endif /* _ANTENNA_H_ */
|
||||
|
||||
@ -25,8 +25,23 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/builtin.h"
|
||||
#include <stdio.h>
|
||||
|
||||
const char *cc3200_help_text = "Welcome to MicroPython!\n"
|
||||
#include "lib/utils/pyhelp.h"
|
||||
|
||||
STATIC const char help_text[] = "Welcome to MicroPython!\n"
|
||||
"For online help please visit http://micropython.org/help/.\n"
|
||||
"For further help on a specific object, type help(obj)\n";
|
||||
|
||||
STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// print a general help message
|
||||
printf("%s", help_text);
|
||||
}
|
||||
else {
|
||||
// try to print something sensible about the given object
|
||||
pyhelp_print_obj(args[0]);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, pyb_help);
|
||||
|
||||
@ -24,8 +24,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MISC_MPERROR_H
|
||||
#define MICROPY_INCLUDED_CC3200_MISC_MPERROR_H
|
||||
|
||||
#ifndef MPERROR_H_
|
||||
#define MPERROR_H_
|
||||
|
||||
extern void NORETURN __fatal_error(const char *msg);
|
||||
|
||||
@ -38,4 +39,4 @@ void mperror_heartbeat_signal (void);
|
||||
void mperror_enable_heartbeat (bool enable);
|
||||
bool mperror_is_heartbeat_enabled (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MISC_MPERROR_H
|
||||
#endif // MPERROR_H_
|
||||
|
||||
@ -40,6 +40,9 @@ STATIC void mpexception_set_user_interrupt (int chr, void *data);
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED DATA
|
||||
******************************************************************************/
|
||||
const char mpexception_os_resource_not_avaliable[] = "resource not available";
|
||||
const char mpexception_os_operation_failed[] = "the requested operation failed";
|
||||
const char mpexception_os_request_not_possible[] = "the requested operation is not possible";
|
||||
const char mpexception_value_invalid_arguments[] = "invalid argument(s) value";
|
||||
const char mpexception_num_type_invalid_arguments[] = "invalid argument(s) num/type";
|
||||
const char mpexception_uncaught[] = "uncaught exception";
|
||||
|
||||
@ -24,9 +24,13 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MISC_MPEXCEPTION_H
|
||||
#define MICROPY_INCLUDED_CC3200_MISC_MPEXCEPTION_H
|
||||
|
||||
#ifndef MPEXCEPTION_H_
|
||||
#define MPEXCEPTION_H_
|
||||
|
||||
extern const char mpexception_os_resource_not_avaliable[];
|
||||
extern const char mpexception_os_operation_failed[];
|
||||
extern const char mpexception_os_request_not_possible[];
|
||||
extern const char mpexception_value_invalid_arguments[];
|
||||
extern const char mpexception_num_type_invalid_arguments[];
|
||||
extern const char mpexception_uncaught[];
|
||||
@ -39,4 +43,4 @@ extern void mpexception_set_interrupt_char (int c);
|
||||
extern void mpexception_nlr_jump (void *o);
|
||||
extern void mpexception_keyboard_nlr_jump (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MISC_MPEXCEPTION_H
|
||||
#endif /* MPEXCEPTION_H_ */
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
@ -112,7 +112,7 @@ void mp_irq_remove (const mp_obj_t parent) {
|
||||
|
||||
uint mp_irq_translate_priority (uint priority) {
|
||||
if (priority < 1 || priority > MP_ARRAY_SIZE(mp_irq_priorities)) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
return mp_irq_priorities[priority - 1];
|
||||
}
|
||||
@ -176,7 +176,7 @@ STATIC mp_obj_t mp_irq_flags (mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_flags_obj, mp_irq_flags);
|
||||
|
||||
STATIC mp_obj_t mp_irq_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t mp_irq_call (mp_obj_t self_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, 0, false);
|
||||
mp_irq_handler (self_in);
|
||||
return mp_const_none;
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MISC_MPIRQ_H
|
||||
#define MICROPY_INCLUDED_CC3200_MISC_MPIRQ_H
|
||||
|
||||
#ifndef MPIRQ_H_
|
||||
#define MPIRQ_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
@ -71,4 +72,4 @@ void mp_irq_remove (const mp_obj_t parent);
|
||||
void mp_irq_handler (mp_obj_t self_in);
|
||||
uint mp_irq_translate_priority (uint priority);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MISC_MPIRQ_H
|
||||
#endif /* MPIRQ_H_ */
|
||||
|
||||
71
cc3200/misc/mpsystick.c
Normal file
71
cc3200/misc/mpsystick.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "mpsystick.h"
|
||||
#include "systick.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#endif
|
||||
|
||||
|
||||
bool sys_tick_has_passed(uint32_t start_tick, uint32_t delay_ms) {
|
||||
return mp_hal_ticks_ms() - start_tick >= delay_ms;
|
||||
}
|
||||
|
||||
// waits until at least delay_ms milliseconds have passed from the sampling of
|
||||
// startTick. Handles overflow properly. Assumes stc was taken from
|
||||
// mp_hal_ticks_ms() some time before calling this function.
|
||||
void sys_tick_wait_at_least(uint32_t start_tick, uint32_t delay_ms) {
|
||||
#ifdef USE_FREERTOS
|
||||
vTaskDelay (delay_ms / portTICK_PERIOD_MS);
|
||||
#else
|
||||
while (!sys_tick_has_passed(start_tick, delay_ms)) {
|
||||
__WFI(); // enter sleep mode, waiting for interrupt
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// The SysTick timer counts down at HAL_FCPU_HZ, so we can use that knowledge
|
||||
// to grab a microsecond counter.
|
||||
// We assume that mp_hal_ticks_ms returns milliseconds.
|
||||
uint32_t sys_tick_get_microseconds(void) {
|
||||
mp_uint_t irq_state = disable_irq();
|
||||
uint32_t counter = SysTickValueGet();
|
||||
uint32_t milliseconds = mp_hal_ticks_ms();
|
||||
enable_irq(irq_state);
|
||||
|
||||
uint32_t load = SysTickPeriodGet();
|
||||
counter = load - counter; // Convert from decrementing to incrementing
|
||||
return (milliseconds * 1000) + ((counter * 1000) / load);
|
||||
}
|
||||
35
cc3200/misc/mpsystick.h
Normal file
35
cc3200/misc/mpsystick.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MPSYSTICK_H
|
||||
#define MPSYSTICK_H
|
||||
|
||||
void sys_tick_wait_at_least(uint32_t stc, uint32_t delay_ms);
|
||||
bool sys_tick_has_passed(uint32_t stc, uint32_t delay_ms);
|
||||
uint32_t sys_tick_get_microseconds(void);
|
||||
|
||||
#endif // MPSYSTICK_H
|
||||
@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
@ -111,7 +112,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_info_obj, 0, 1, machine_info)
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t machine_freq(void) {
|
||||
return mp_obj_new_int(HAL_FCPU_HZ);
|
||||
mp_obj_t tuple[1] = {
|
||||
mp_obj_new_int(HAL_FCPU_HZ),
|
||||
};
|
||||
return mp_obj_new_tuple(1, tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_freq_obj, machine_freq);
|
||||
|
||||
@ -126,7 +130,7 @@ STATIC mp_obj_t machine_main(mp_obj_t main) {
|
||||
if (MP_OBJ_IS_STR(main)) {
|
||||
MP_STATE_PORT(machine_config_main) = main;
|
||||
} else {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -209,5 +213,6 @@ STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table
|
||||
|
||||
const mp_obj_module_t machine_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_umachine,
|
||||
.globals = (mp_obj_dict_t*)&machine_module_globals,
|
||||
};
|
||||
|
||||
@ -25,11 +25,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "modnetwork.h"
|
||||
#include "mpexception.h"
|
||||
@ -90,7 +91,7 @@ STATIC const mp_arg_t network_server_args[] = {
|
||||
{ MP_QSTR_login, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t network_server_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t network_server_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -100,7 +101,7 @@ STATIC mp_obj_t network_server_make_new(const mp_obj_type_t *type, size_t n_args
|
||||
// check the server id
|
||||
if (args[0].u_obj != MP_OBJ_NULL) {
|
||||
if (mp_obj_get_int(args[0].u_obj) != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +161,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals
|
||||
|
||||
const mp_obj_module_t mp_module_network = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_network,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_network_globals,
|
||||
};
|
||||
|
||||
|
||||
@ -24,8 +24,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_MODNETWORK_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_MODNETWORK_H
|
||||
|
||||
#ifndef MODNETWORK_H_
|
||||
#define MODNETWORK_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
@ -51,7 +52,7 @@ typedef struct _mod_network_socket_base_t {
|
||||
} u_param;
|
||||
int16_t sd;
|
||||
};
|
||||
uint32_t timeout_ms; // 0 for no timeout
|
||||
bool has_timeout;
|
||||
bool cert_req;
|
||||
} mod_network_socket_base_t;
|
||||
|
||||
@ -70,4 +71,4 @@ extern const mod_network_nic_type_t mod_network_nic_type_wlan;
|
||||
******************************************************************************/
|
||||
void mod_network_init0(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_MODNETWORK_H
|
||||
#endif // MODNETWORK_H_
|
||||
|
||||
@ -58,5 +58,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globa
|
||||
|
||||
const mp_obj_module_t mp_module_ubinascii = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_ubinascii,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_binascii_globals,
|
||||
};
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_MODUBINASCII_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_MODUBINASCII_H
|
||||
|
||||
#ifndef MODUBINASCII_H_
|
||||
#define MODUBINASCII_H_
|
||||
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_MODUBINASCII_H
|
||||
#endif /* MODUBINASCII_H_ */
|
||||
|
||||
@ -93,7 +93,7 @@ STATIC void hash_update_internal(mp_obj_t self_in, mp_obj_t data, bool digest) {
|
||||
self->digested = false;
|
||||
}
|
||||
} else {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ STATIC mp_obj_t hash_read (mp_obj_t self_in) {
|
||||
}
|
||||
} else if (self->c_size < self->b_size) {
|
||||
// it's a fixed len block which is still incomplete
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
if (!self->digested) {
|
||||
@ -121,7 +121,7 @@ STATIC mp_obj_t hash_read (mp_obj_t self_in) {
|
||||
|
||||
/// \classmethod \constructor([data[, block_size]])
|
||||
/// initial data must be given if block_size wants to be passed
|
||||
STATIC mp_obj_t hash_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t hash_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, 2, false);
|
||||
mp_obj_hash_t *self = m_new0(mp_obj_hash_t, 1);
|
||||
self->base.type = type_in;
|
||||
@ -204,6 +204,7 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_hashlib_globals, mp_module_hashlib_globals
|
||||
|
||||
const mp_obj_module_t mp_module_uhashlib = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_uhashlib,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_hashlib_globals,
|
||||
};
|
||||
|
||||
|
||||
@ -33,17 +33,15 @@
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "moduos.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "extmod/vfs_fat_file.h"
|
||||
#include "random.h"
|
||||
#include "mpexception.h"
|
||||
#include "version.h"
|
||||
#include "timeutils.h"
|
||||
#include "pybsd.h"
|
||||
#include "pybuart.h"
|
||||
|
||||
@ -61,20 +59,155 @@
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC uint32_t os_num_mounted_devices;
|
||||
STATIC os_term_dup_obj_t os_term_dup_obj;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void unmount (os_fs_mount_t *mount_obj);
|
||||
STATIC bool path_equal(const char *path, const char *path_canonical);
|
||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string);
|
||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
void moduos_init0 (void) {
|
||||
// initialize the mount objects list
|
||||
mp_obj_list_init(&MP_STATE_PORT(mount_obj_list), 0);
|
||||
os_num_mounted_devices = 0;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (!strcmp(path, mount_obj->path)) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (vol == mount_obj->vol) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_device (mp_obj_t device) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (device == mount_obj->device) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void osmount_unmount_all (void) {
|
||||
//TODO
|
||||
/*
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
unmount(mount_obj);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
// path_equal(/flash//, /flash) -> true
|
||||
// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
|
||||
STATIC bool path_equal(const char *path, const char *path_canonical) {
|
||||
for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
|
||||
}
|
||||
if (*path_canonical != '\0') {
|
||||
return false;
|
||||
}
|
||||
for (; *path == '/'; ++path) {
|
||||
}
|
||||
return *path == '\0';
|
||||
}
|
||||
|
||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string) {
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
if (string) {
|
||||
entry_o = mp_obj_new_str(item, strlen(item), false);
|
||||
} else {
|
||||
entry_o = mp_obj_new_bytes((const byte*)item, strlen(item));
|
||||
}
|
||||
|
||||
// add the entry to the list
|
||||
mp_obj_list_append(dirlist, entry_o);
|
||||
}
|
||||
|
||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly) {
|
||||
// is the mount point already in use?
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
// cannot mount twice or on existing paths
|
||||
if (f_stat(path, &fno) == FR_OK || osmount_find_by_device(device)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// create a new object
|
||||
os_fs_mount_t *self = m_new_obj(os_fs_mount_t);
|
||||
self->device = device;
|
||||
self->path = path;
|
||||
self->pathlen = pathlen;
|
||||
self->vol = os_num_mounted_devices + 1; // '/flash' is volume 0
|
||||
|
||||
if (device == (mp_obj_t)&pybsd_obj) {
|
||||
// need to make it different to NULL, otherwise it's read only by default
|
||||
self->writeblocks[0] = mp_const_none;
|
||||
self->sync[0] = MP_OBJ_NULL; // no need to sync the SD card
|
||||
self->count[0] = MP_OBJ_NULL;
|
||||
} else {
|
||||
// load block protocol methods
|
||||
mp_load_method(device, MP_QSTR_readblocks, self->readblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_writeblocks, self->writeblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_sync, self->sync);
|
||||
mp_load_method(device, MP_QSTR_count, self->count);
|
||||
}
|
||||
|
||||
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
||||
// User can specify read-only device by:
|
||||
// 1. readonly=True keyword argument
|
||||
// 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
|
||||
if (readonly) {
|
||||
self->writeblocks[0] = MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
// we need to add it before doing the actual mount, so that the volume can be found
|
||||
mp_obj_list_append(&MP_STATE_PORT(mount_obj_list), self);
|
||||
|
||||
// actually mount it
|
||||
if (f_mount(&self->fatfs, self->path, 1) != FR_OK) {
|
||||
// remove it and raise
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), self);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// mount succeeded, increment the count
|
||||
os_num_mounted_devices++;
|
||||
}
|
||||
|
||||
STATIC void unmount (os_fs_mount_t *mount_obj) {
|
||||
// remove it from the list and then call FatFs
|
||||
f_mount (NULL, mount_obj->path, 1);
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), mount_obj);
|
||||
os_num_mounted_devices--;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -106,6 +239,193 @@ STATIC mp_obj_t os_uname(void) {
|
||||
}
|
||||
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) {
|
||||
const char *path;
|
||||
path = mp_obj_str_get_str(path_in);
|
||||
|
||||
FRESULT res = f_chdrive(path);
|
||||
|
||||
if (res == FR_OK) {
|
||||
res = f_chdir(path);
|
||||
}
|
||||
|
||||
if (res != FR_OK) {
|
||||
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_chdir_obj, os_chdir);
|
||||
|
||||
STATIC mp_obj_t os_getcwd(void) {
|
||||
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
||||
FRESULT res = f_getcwd(buf, sizeof buf);
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
return mp_obj_new_str(buf, strlen(buf), false);
|
||||
}
|
||||
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;
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
|
||||
if (n_args == 1) {
|
||||
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
|
||||
is_str_type = false;
|
||||
}
|
||||
path = mp_obj_str_get_str(args[0]);
|
||||
} else {
|
||||
path = "";
|
||||
}
|
||||
|
||||
// "hack" to list the root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
// add 'flash' to the list
|
||||
append_dir_item (dir_list, "flash", is_str_type);
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
append_dir_item (dir_list, &mount_obj->path[1], is_str_type);
|
||||
}
|
||||
} else {
|
||||
FRESULT res;
|
||||
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) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
for ( ; ; ) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
|
||||
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
|
||||
|
||||
// add the entry to the list
|
||||
append_dir_item (dir_list, fn, is_str_type);
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
|
||||
return dir_list;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
|
||||
|
||||
STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_mkdir(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
case FR_EXIST:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
break;
|
||||
default:
|
||||
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);
|
||||
|
||||
STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
|
||||
const char *old_path = mp_obj_str_get_str(path_in);
|
||||
const char *new_path = mp_obj_str_get_str(path_out);
|
||||
FRESULT res = f_rename(old_path, new_path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
||||
|
||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
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);
|
||||
|
||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
bool isbuilt_in = false;
|
||||
FILINFO fno;
|
||||
FRESULT res;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
// check on the user mounted devices
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (path_equal(path, mount_obj->path)) {
|
||||
isbuilt_in = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (path_equal(path, "/") || path_equal(path, "/flash") || isbuilt_in) {
|
||||
// stat built-in directory
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
} else if ((res = f_stat(path, &fno)) != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
|
||||
mp_int_t mode = 0;
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
mode |= 0x4000; // stat.S_IFDIR
|
||||
} else {
|
||||
mode |= 0x8000; // stat.S_IFREG
|
||||
}
|
||||
mp_int_t seconds = timeutils_seconds_since_2000(
|
||||
1980 + ((fno.fdate >> 9) & 0x7f),
|
||||
(fno.fdate >> 5) & 0x0f,
|
||||
fno.fdate & 0x1f,
|
||||
(fno.ftime >> 11) & 0x1f,
|
||||
(fno.ftime >> 5) & 0x3f,
|
||||
2 * (fno.ftime & 0x1f)
|
||||
);
|
||||
t->items[0] = mp_obj_new_int(mode); // st_mode
|
||||
t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
|
||||
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
|
||||
t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
|
||||
t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
|
||||
t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
|
||||
t->items[6] = mp_obj_new_int(fno.fsize); // st_size
|
||||
t->items[7] = mp_obj_new_int(seconds); // st_atime
|
||||
t->items[8] = t->items[7]; // st_mtime
|
||||
t->items[9] = t->items[7]; // st_ctime
|
||||
return t;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
@ -123,6 +443,110 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
|
||||
STATIC mp_obj_t os_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t mount_args[] = {
|
||||
{ MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_obj_t device = pos_args[0];
|
||||
mp_obj_t mount_point = pos_args[1];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(mount_args)];
|
||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(mount_args), mount_args, args);
|
||||
|
||||
// get the mount point
|
||||
mp_uint_t pathlen;
|
||||
const char *path_in = mp_obj_str_get_data(mount_point, &pathlen);
|
||||
if (pathlen == 0) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
char *path = m_new(char, pathlen + 1);
|
||||
memcpy(path, path_in, pathlen);
|
||||
path[pathlen] = '\0';
|
||||
|
||||
// "remove" any extra slahes at the end
|
||||
while (path[(pathlen - 1)] == '/') {
|
||||
path[--pathlen] = '\0';
|
||||
}
|
||||
|
||||
// is the mount point valid?
|
||||
if (pathlen < 2 || path[0] !='/' || strchr(&path[1], '/')) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// now mount it
|
||||
mount(device, path, pathlen, args[0].u_bool);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(os_mount_obj, 2, os_mount);
|
||||
|
||||
STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
|
||||
// '/flash' cannot be unmounted, also not the current working directory
|
||||
if (path_equal(path, "/flash")) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// now unmount it
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_path(path))) {
|
||||
unmount (mount_obj);
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_unmount_obj, os_unmount);
|
||||
|
||||
STATIC mp_obj_t os_mkfs(mp_obj_t device) {
|
||||
const char *path = "/__mkfs__mnt__";
|
||||
os_fs_mount_t *mount_obj = NULL;
|
||||
bool unmt = false;
|
||||
FRESULT res;
|
||||
|
||||
if (MP_OBJ_IS_STR_OR_BYTES(device)) {
|
||||
path = mp_obj_str_get_str(device);
|
||||
// otherwise the relative path check will pass...
|
||||
if (path[0] != '/') {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
} else {
|
||||
// mount it briefly
|
||||
mount(device, path, strlen(path), false);
|
||||
unmt = true;
|
||||
}
|
||||
|
||||
byte sfd = 0;
|
||||
if (!memcmp(path, "/flash", strlen("/flash"))) {
|
||||
sfd = 1;
|
||||
} else if ((mount_obj = osmount_find_by_path(path))) {
|
||||
if (mount_obj->device != (mp_obj_t)&pybsd_obj &&
|
||||
mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count)) < 2048) {
|
||||
sfd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// now format the device
|
||||
res = f_mkfs(path, sfd, 0);
|
||||
|
||||
if (unmt && mount_obj) {
|
||||
unmount (mount_obj);
|
||||
}
|
||||
|
||||
if (res != FR_OK) {
|
||||
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_mkfs_obj, os_mkfs);
|
||||
|
||||
STATIC mp_obj_t os_dupterm(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
if (MP_STATE_PORT(os_term_dup_obj) == MP_OBJ_NULL) {
|
||||
@ -152,33 +576,32 @@ 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_uname), (mp_obj_t)&os_uname_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&mp_vfs_chdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&mp_vfs_getcwd_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ilistdir), (mp_obj_t)&mp_vfs_ilistdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&mp_vfs_listdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&mp_vfs_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rename), (mp_obj_t)&mp_vfs_rename_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&mp_vfs_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&mp_vfs_rmdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&mp_vfs_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&mp_vfs_remove_obj }, // unlink aliases to remove
|
||||
|
||||
{ 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_rename), (mp_obj_t)&os_rename_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 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
|
||||
// MicroPython additions
|
||||
// removed: mkfs
|
||||
// renamed: unmount -> umount
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&mp_vfs_mount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_umount), (mp_obj_t)&mp_vfs_umount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_VfsFat), (mp_obj_t)&mp_fat_vfs_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&os_mount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&os_unmount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&os_mkfs_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&os_dupterm_obj },
|
||||
|
||||
/// \constant sep - separation character used in paths
|
||||
{ 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);
|
||||
|
||||
const mp_obj_module_t mp_module_uos = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_uos,
|
||||
.globals = (mp_obj_dict_t*)&os_module_globals,
|
||||
};
|
||||
|
||||
@ -24,14 +24,26 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_MODUOS_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_MODUOS_H
|
||||
|
||||
#include "py/obj.h"
|
||||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _os_fs_mount_t {
|
||||
mp_obj_t device;
|
||||
const char *path;
|
||||
mp_uint_t pathlen;
|
||||
mp_obj_t readblocks[4];
|
||||
mp_obj_t writeblocks[4];
|
||||
mp_obj_t sync[2];
|
||||
mp_obj_t count[2];
|
||||
FATFS fatfs;
|
||||
uint8_t vol;
|
||||
} os_fs_mount_t;
|
||||
|
||||
typedef struct _os_term_dup_obj_t {
|
||||
mp_obj_t stream_o;
|
||||
@ -42,6 +54,9 @@ typedef struct _os_term_dup_obj_t {
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void moduos_init0 (void);
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path);
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol);
|
||||
void osmount_unmount_all (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_MODUOS_H
|
||||
#endif // MODUOS_H_
|
||||
|
||||
@ -34,315 +34,12 @@
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
#include "netutils.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "modusocket.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
/******************************************************************************/
|
||||
// The following set of macros and functions provide a glue between the CC3100
|
||||
// simplelink layer and the functions/methods provided by the usocket module.
|
||||
// They were historically in a separate file because usocket was designed to
|
||||
// work with multiple NICs, and the wlan_XXX functions just provided one
|
||||
// particular NIC implementation (that of the CC3100). But the CC3200 port only
|
||||
// supports a single NIC (being the CC3100) so it's unnecessary and inefficient
|
||||
// to provide an intermediate wrapper layer. Hence the wlan_XXX functions
|
||||
// are provided below as static functions so they can be inlined directly by
|
||||
// the corresponding usocket calls.
|
||||
|
||||
#define WLAN_MAX_RX_SIZE 16000
|
||||
#define WLAN_MAX_TX_SIZE 1476
|
||||
|
||||
#define MAKE_SOCKADDR(addr, ip, port) SlSockAddr_t addr; \
|
||||
addr.sa_family = SL_AF_INET; \
|
||||
addr.sa_data[0] = port >> 8; \
|
||||
addr.sa_data[1] = port; \
|
||||
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[5]; \
|
||||
ip[1] = addr.sa_data[4]; \
|
||||
ip[2] = addr.sa_data[3]; \
|
||||
ip[3] = addr.sa_data[2];
|
||||
|
||||
#define SOCKET_TIMEOUT_QUANTA_MS (20)
|
||||
|
||||
STATIC int convert_sl_errno(int sl_errno) {
|
||||
return -sl_errno;
|
||||
}
|
||||
|
||||
// This function is left as non-static so it's not inlined.
|
||||
int check_timedout(mod_network_socket_obj_t *s, int ret, uint32_t *timeout_ms, int *_errno) {
|
||||
if (*timeout_ms == 0 || ret != SL_EAGAIN) {
|
||||
if (s->sock_base.timeout_ms > 0 && ret == SL_EAGAIN) {
|
||||
*_errno = MP_ETIMEDOUT;
|
||||
} else {
|
||||
*_errno = convert_sl_errno(ret);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
mp_hal_delay_ms(SOCKET_TIMEOUT_QUANTA_MS);
|
||||
if (*timeout_ms < SOCKET_TIMEOUT_QUANTA_MS) {
|
||||
*timeout_ms = 0;
|
||||
} else {
|
||||
*timeout_ms -= SOCKET_TIMEOUT_QUANTA_MS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family) {
|
||||
uint32_t ip;
|
||||
int result = sl_NetAppDnsGetHostByName((_i8 *)name, (_u16)len, (_u32*)&ip, (_u8)family);
|
||||
out_ip[0] = ip;
|
||||
out_ip[1] = ip >> 8;
|
||||
out_ip[2] = ip >> 16;
|
||||
out_ip[3] = ip >> 24;
|
||||
return result;
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno) {
|
||||
int16_t sd = sl_Socket(s->sock_base.u_param.domain, s->sock_base.u_param.type, s->sock_base.u_param.proto);
|
||||
if (sd < 0) {
|
||||
*_errno = sd;
|
||||
return -1;
|
||||
}
|
||||
s->sock_base.sd = sd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC void wlan_socket_close(mod_network_socket_obj_t *s) {
|
||||
// this is to prevent the finalizer to close a socket that failed when being created
|
||||
if (s->sock_base.sd >= 0) {
|
||||
modusocket_socket_delete(s->sock_base.sd);
|
||||
sl_Close(s->sock_base.sd);
|
||||
s->sock_base.sd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
|
||||
MAKE_SOCKADDR(addr, ip, port)
|
||||
int ret = sl_Bind(s->sock_base.sd, &addr, sizeof(addr));
|
||||
if (ret != 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_listen(mod_network_socket_obj_t *s, mp_int_t backlog, int *_errno) {
|
||||
int ret = sl_Listen(s->sock_base.sd, backlog);
|
||||
if (ret != 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2, byte *ip, mp_uint_t *port, int *_errno) {
|
||||
// accept incoming connection
|
||||
int16_t sd;
|
||||
SlSockAddr_t addr;
|
||||
SlSocklen_t addr_len = sizeof(addr);
|
||||
|
||||
uint32_t timeout_ms = s->sock_base.timeout_ms;
|
||||
for (;;) {
|
||||
sd = sl_Accept(s->sock_base.sd, &addr, &addr_len);
|
||||
if (sd >= 0) {
|
||||
// save the socket descriptor
|
||||
s2->sock_base.sd = sd;
|
||||
// return ip and port
|
||||
UNPACK_SOCKADDR(addr, ip, *port);
|
||||
return 0;
|
||||
}
|
||||
if (check_timedout(s, sd, &timeout_ms, _errno)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
|
||||
MAKE_SOCKADDR(addr, ip, port)
|
||||
uint32_t timeout_ms = s->sock_base.timeout_ms;
|
||||
|
||||
// For a non-blocking connect the CC3100 will return SL_EALREADY while the
|
||||
// connection is in progress.
|
||||
|
||||
for (;;) {
|
||||
int ret = sl_Connect(s->sock_base.sd, &addr, sizeof(addr));
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if we are in non-blocking mode and the connection is in progress
|
||||
if (s->sock_base.timeout_ms == 0 && ret == SL_EALREADY) {
|
||||
// To match BSD we return EINPROGRESS here
|
||||
*_errno = MP_EINPROGRESS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We are in blocking mode, so if the connection isn't in progress then error out
|
||||
if (ret != SL_EALREADY) {
|
||||
*_errno = convert_sl_errno(ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (check_timedout(s, SL_EAGAIN, &timeout_ms, _errno)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno) {
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t timeout_ms = s->sock_base.timeout_ms;
|
||||
for (;;) {
|
||||
int ret = sl_Send(s->sock_base.sd, (const void *)buf, len, 0);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
if (check_timedout(s, ret, &timeout_ms, _errno)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno) {
|
||||
uint32_t timeout_ms = s->sock_base.timeout_ms;
|
||||
for (;;) {
|
||||
int ret = sl_Recv(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0);
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
}
|
||||
if (check_timedout(s, ret, &timeout_ms, _errno)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) {
|
||||
MAKE_SOCKADDR(addr, ip, port)
|
||||
uint32_t timeout_ms = s->sock_base.timeout_ms;
|
||||
for (;;) {
|
||||
int ret = sl_SendTo(s->sock_base.sd, (byte*)buf, len, 0, (SlSockAddr_t*)&addr, sizeof(addr));
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
}
|
||||
if (check_timedout(s, ret, &timeout_ms, _errno)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
|
||||
SlSockAddr_t addr;
|
||||
SlSocklen_t addr_len = sizeof(addr);
|
||||
uint32_t timeout_ms = s->sock_base.timeout_ms;
|
||||
for (;;) {
|
||||
int ret = sl_RecvFrom(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0, &addr, &addr_len);
|
||||
if (ret >= 0) {
|
||||
UNPACK_SOCKADDR(addr, ip, *port);
|
||||
return ret;
|
||||
}
|
||||
if (check_timedout(s, ret, &timeout_ms, _errno)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) {
|
||||
int ret = sl_SetSockOpt(s->sock_base.sd, level, opt, optval, optlen);
|
||||
if (ret < 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int *_errno) {
|
||||
SlSockNonblocking_t option;
|
||||
if (timeout_s == 0 || timeout_s == -1) {
|
||||
if (timeout_s == 0) {
|
||||
// set non-blocking mode
|
||||
option.NonblockingEnabled = 1;
|
||||
} else {
|
||||
// set blocking mode
|
||||
option.NonblockingEnabled = 0;
|
||||
}
|
||||
timeout_s = 0;
|
||||
} else {
|
||||
// synthesize timeout via non-blocking behaviour with a loop
|
||||
option.NonblockingEnabled = 1;
|
||||
}
|
||||
|
||||
int ret = sl_SetSockOpt(s->sock_base.sd, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &option, sizeof(option));
|
||||
if (ret != 0) {
|
||||
*_errno = convert_sl_errno(ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->sock_base.timeout_ms = timeout_s * 1000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t arg, int *_errno) {
|
||||
mp_int_t ret;
|
||||
if (request == MP_STREAM_POLL) {
|
||||
mp_uint_t flags = arg;
|
||||
ret = 0;
|
||||
int32_t sd = s->sock_base.sd;
|
||||
|
||||
// init fds
|
||||
SlFdSet_t rfds, wfds, xfds;
|
||||
SL_FD_ZERO(&rfds);
|
||||
SL_FD_ZERO(&wfds);
|
||||
SL_FD_ZERO(&xfds);
|
||||
|
||||
// set fds if needed
|
||||
if (flags & MP_STREAM_POLL_RD) {
|
||||
SL_FD_SET(sd, &rfds);
|
||||
}
|
||||
if (flags & MP_STREAM_POLL_WR) {
|
||||
SL_FD_SET(sd, &wfds);
|
||||
}
|
||||
if (flags & MP_STREAM_POLL_HUP) {
|
||||
SL_FD_SET(sd, &xfds);
|
||||
}
|
||||
|
||||
// call simplelink's select with minimum timeout
|
||||
SlTimeval_t tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1;
|
||||
int32_t nfds = sl_Select(sd + 1, &rfds, &wfds, &xfds, &tv);
|
||||
|
||||
// check for errors
|
||||
if (nfds == -1) {
|
||||
*_errno = nfds;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check return of select
|
||||
if (SL_FD_ISSET(sd, &rfds)) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
}
|
||||
if (SL_FD_ISSET(sd, &wfds)) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
}
|
||||
if (SL_FD_ISSET(sd, &xfds)) {
|
||||
ret |= MP_STREAM_POLL_HUP;
|
||||
}
|
||||
} else {
|
||||
*_errno = MP_EINVAL;
|
||||
ret = MP_STREAM_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
******************************************************************************/
|
||||
@ -398,13 +95,13 @@ void modusocket_socket_delete (int16_t sd) {
|
||||
}
|
||||
|
||||
void modusocket_enter_sleep (void) {
|
||||
SlFdSet_t socketset;
|
||||
fd_set socketset;
|
||||
int16_t maxfd = 0;
|
||||
|
||||
for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
|
||||
int16_t sd;
|
||||
if ((sd = modusocket_sockets[i].sd) >= 0) {
|
||||
SL_FD_SET(sd, &socketset);
|
||||
FD_SET(sd, &socketset);
|
||||
maxfd = (maxfd > sd) ? maxfd : sd;
|
||||
}
|
||||
}
|
||||
@ -430,17 +127,17 @@ void modusocket_close_all_user_sockets (void) {
|
||||
// socket class
|
||||
|
||||
// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
|
||||
STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, 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);
|
||||
|
||||
// create socket object
|
||||
mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
|
||||
s->base.type = (mp_obj_t)&socket_type;
|
||||
s->sock_base.u_param.domain = SL_AF_INET;
|
||||
s->sock_base.u_param.type = SL_SOCK_STREAM;
|
||||
s->sock_base.u_param.proto = SL_IPPROTO_TCP;
|
||||
s->sock_base.u_param.domain = AF_INET;
|
||||
s->sock_base.u_param.type = SOCK_STREAM;
|
||||
s->sock_base.u_param.proto = IPPROTO_TCP;
|
||||
s->sock_base.u_param.fileno = -1;
|
||||
s->sock_base.timeout_ms = 0;
|
||||
s->sock_base.has_timeout = false;
|
||||
s->sock_base.cert_req = false;
|
||||
|
||||
if (n_args > 0) {
|
||||
@ -459,7 +156,7 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t
|
||||
// create the socket
|
||||
int _errno;
|
||||
if (wlan_socket_socket(s, &_errno) != 0) {
|
||||
mp_raise_OSError(-_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
// add the socket to the list
|
||||
modusocket_socket_add(s->sock_base.sd, true);
|
||||
@ -483,9 +180,9 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// call the NIC to bind the socket
|
||||
int _errno = 0;
|
||||
int _errno;
|
||||
if (wlan_socket_bind(self, ip, port, &_errno) != 0) {
|
||||
mp_raise_OSError(-_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -503,7 +200,7 @@ STATIC mp_obj_t socket_listen(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
|
||||
int _errno;
|
||||
if (wlan_socket_listen(self, backlog, &_errno) != 0) {
|
||||
mp_raise_OSError(-_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -520,10 +217,10 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
|
||||
|
||||
// accept the incoming connection
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port = 0;
|
||||
int _errno = 0;
|
||||
mp_uint_t port;
|
||||
int _errno;
|
||||
if (wlan_socket_accept(self, socket2, ip, &port, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
|
||||
// add the socket to the list
|
||||
@ -551,7 +248,7 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
if (!self->sock_base.cert_req && _errno == SL_ESECSNOVERIFY) {
|
||||
return mp_const_none;
|
||||
}
|
||||
mp_raise_OSError(_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -565,7 +262,7 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
int _errno;
|
||||
mp_int_t ret = wlan_socket_send(self, bufinfo.buf, bufinfo.len, &_errno);
|
||||
if (ret < 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_obj_new_int_from_uint(ret);
|
||||
}
|
||||
@ -580,7 +277,10 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
int _errno;
|
||||
mp_int_t ret = wlan_socket_recv(self, (byte*)vstr.buf, len, &_errno);
|
||||
if (ret < 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
if (_errno == EAGAIN && self->sock_base.has_timeout) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
|
||||
}
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
if (ret == 0) {
|
||||
return mp_const_empty_bytes;
|
||||
@ -604,10 +304,10 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// call the nic to sendto
|
||||
int _errno = 0;
|
||||
int _errno;
|
||||
mp_int_t ret = wlan_socket_sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
|
||||
if (ret < 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
@ -619,11 +319,14 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(len_in));
|
||||
byte ip[4];
|
||||
mp_uint_t port = 0;
|
||||
int _errno = 0;
|
||||
mp_uint_t port;
|
||||
int _errno;
|
||||
mp_int_t ret = wlan_socket_recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno);
|
||||
if (ret < 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
if (_errno == EAGAIN && self->sock_base.has_timeout) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
|
||||
}
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
mp_obj_t tuple[2];
|
||||
if (ret == 0) {
|
||||
@ -661,7 +364,7 @@ STATIC mp_obj_t socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
|
||||
int _errno;
|
||||
if (wlan_socket_setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
|
||||
mp_raise_OSError(-_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -679,9 +382,9 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
|
||||
} else {
|
||||
timeout = mp_obj_get_int(timeout_in);
|
||||
}
|
||||
int _errno = 0;
|
||||
int _errno;
|
||||
if (wlan_socket_settimeout(self, timeout, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -698,8 +401,17 @@ STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
|
||||
|
||||
STATIC mp_obj_t socket_makefile(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
return args[0];
|
||||
// TODO: CPython explicitly says that closing the returned object doesn't
|
||||
// close the original socket (Python2 at all says that fd is dup()ed). But
|
||||
// we save on the bloat.
|
||||
mod_network_socket_obj_t *self = args[0];
|
||||
if (n_args > 1) {
|
||||
const char *mode = mp_obj_str_get_str(args[1]);
|
||||
if (strcmp(mode, "rb") && strcmp(mode, "wb")) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_makefile_obj, 1, 6, socket_makefile);
|
||||
|
||||
@ -721,7 +433,8 @@ STATIC const mp_map_elem_t socket_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_makefile), (mp_obj_t)&socket_makefile_obj },
|
||||
|
||||
// stream methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read1_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
|
||||
@ -733,10 +446,12 @@ STATIC mp_uint_t socket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *e
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
mp_int_t ret = wlan_socket_recv(self, buf, size, errcode);
|
||||
if (ret < 0) {
|
||||
// we need to ignore the socket closed error here because a read() without params
|
||||
// we need to ignore the socket closed error here because a readall() or read() without params
|
||||
// only returns when the socket is closed by the other end
|
||||
if (*errcode != -SL_ESECCLOSED) {
|
||||
if (*errcode != SL_ESECCLOSED) {
|
||||
ret = MP_STREAM_ERROR;
|
||||
// needed to convert simplelink's negative error codes to POSIX
|
||||
(*errcode) *= -1;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
@ -749,6 +464,8 @@ STATIC mp_uint_t socket_write(mp_obj_t self_in, const void *buf, mp_uint_t size,
|
||||
mp_int_t ret = wlan_socket_send(self, buf, size, errcode);
|
||||
if (ret < 0) {
|
||||
ret = MP_STREAM_ERROR;
|
||||
// needed to convert simplelink's negative error codes to POSIX
|
||||
(*errcode) *= -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -779,19 +496,19 @@ STATIC const mp_obj_type_t socket_type = {
|
||||
// function usocket.getaddrinfo(host, port)
|
||||
/// \function getaddrinfo(host, port)
|
||||
STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
|
||||
size_t hlen;
|
||||
mp_uint_t hlen;
|
||||
const char *host = mp_obj_str_get_data(host_in, &hlen);
|
||||
mp_int_t port = mp_obj_get_int(port_in);
|
||||
|
||||
// ipv4 only
|
||||
uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
int32_t result = wlan_gethostbyname(host, hlen, out_ip, SL_AF_INET);
|
||||
int32_t result = wlan_gethostbyname(host, hlen, out_ip, AF_INET);
|
||||
if (result < 0) {
|
||||
mp_raise_OSError(-result);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-result)));
|
||||
}
|
||||
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(SL_AF_INET);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SL_SOCK_STREAM);
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET);
|
||||
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] = netutils_format_inet_addr(out_ip, port, NETUTILS_LITTLE);
|
||||
@ -805,20 +522,25 @@ STATIC const mp_map_elem_t mp_module_usocket_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&mod_usocket_getaddrinfo_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(SL_AF_INET) },
|
||||
// class exceptions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_error), (mp_obj_t)&mp_type_OSError },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_timeout), (mp_obj_t)&mp_type_TimeoutError },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(SL_SOCK_STREAM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(SL_SOCK_DGRAM) },
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(AF_INET) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(SOCK_STREAM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(SOCK_DGRAM) },
|
||||
|
||||
{ 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(SL_IPPROTO_TCP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(SL_IPPROTO_UDP) },
|
||||
{ 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) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_usocket_globals, mp_module_usocket_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_usocket = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_usocket,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_usocket_globals,
|
||||
};
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_MODUSOCKET_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_MODUSOCKET_H
|
||||
|
||||
#ifndef MODUSOCKET_H_
|
||||
#define MODUSOCKET_H_
|
||||
|
||||
extern const mp_obj_dict_t socket_locals_dict;
|
||||
extern const mp_stream_p_t socket_stream_p;
|
||||
@ -35,4 +36,4 @@ extern void modusocket_socket_delete (int16_t sd);
|
||||
extern void modusocket_enter_sleep (void);
|
||||
extern void modusocket_close_all_user_sockets (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_MODUSOCKET_H
|
||||
#endif /* MODUSOCKET_H_ */
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "simplelink.h"
|
||||
#include "py/mpconfig.h"
|
||||
@ -77,7 +78,6 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
|
||||
{ MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
|
||||
{ MP_QSTR_ssl_version, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SL_SO_SEC_METHOD_TLSV1} },
|
||||
{ MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
@ -93,19 +93,17 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
|
||||
// retrieve the file paths (with an 6 byte offset in order to strip it from the '/flash' prefix)
|
||||
const char *keyfile = (args[1].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[1].u_obj)[6]);
|
||||
const char *certfile = (args[2].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[2].u_obj)[6]);
|
||||
const char *cafile = (args[6].u_obj == mp_const_none || args[4].u_int != SSL_CERT_REQUIRED) ?
|
||||
NULL : &(mp_obj_str_get_str(args[6].u_obj)[6]);
|
||||
const char *cafile = (args[5].u_obj == mp_const_none || args[4].u_int != SSL_CERT_REQUIRED) ?
|
||||
NULL : &(mp_obj_str_get_str(args[5].u_obj)[6]);
|
||||
|
||||
// server side requires both certfile and keyfile
|
||||
if (args[3].u_bool && (!keyfile || !certfile)) {
|
||||
goto arg_error;
|
||||
}
|
||||
|
||||
_i16 _errno;
|
||||
_i16 sd = ((mod_network_socket_obj_t *)args[0].u_obj)->sock_base.sd;
|
||||
|
||||
// set the requested SSL method
|
||||
_u8 method = args[5].u_int;
|
||||
_i16 _errno;
|
||||
_u8 method = SL_SO_SEC_METHOD_TLSV1;
|
||||
if ((_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method))) < 0) {
|
||||
goto socket_error;
|
||||
}
|
||||
@ -130,10 +128,10 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
|
||||
return ssl_sock;
|
||||
|
||||
socket_error:
|
||||
mp_raise_OSError(_errno);
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
|
||||
arg_error:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 0, mod_ssl_wrap_socket);
|
||||
|
||||
@ -148,17 +146,13 @@ STATIC const mp_map_elem_t mp_module_ussl_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_NONE), MP_OBJ_NEW_SMALL_INT(SSL_CERT_NONE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_OPTIONAL), MP_OBJ_NEW_SMALL_INT(SSL_CERT_OPTIONAL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_REQUIRED), MP_OBJ_NEW_SMALL_INT(SSL_CERT_REQUIRED) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_SSLv3), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_SSLV3) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_TLSv1), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_TLSV1) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_TLSv1_1), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_TLSV1_1) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROTOCOL_TLSv1_2), MP_OBJ_NEW_SMALL_INT(SL_SO_SEC_METHOD_TLSV1_2) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_ussl_globals, mp_module_ussl_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ussl = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_ussl,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_ussl_globals,
|
||||
};
|
||||
|
||||
|
||||
@ -29,12 +29,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "extmod/utime_mphal.h"
|
||||
#include "timeutils.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@ -42,6 +41,7 @@
|
||||
#include "prcm.h"
|
||||
#include "systick.h"
|
||||
#include "pybrtc.h"
|
||||
#include "mpsystick.h"
|
||||
#include "mpexception.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -102,14 +102,14 @@ STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
|
||||
|
||||
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
||||
size_t len;
|
||||
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) {
|
||||
mp_raise_TypeError(mpexception_num_type_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
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]),
|
||||
@ -131,6 +131,50 @@ STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
|
||||
|
||||
STATIC mp_obj_t time_sleep_ms (mp_obj_t ms_in) {
|
||||
mp_int_t ms = mp_obj_get_int(ms_in);
|
||||
if (ms > 0) {
|
||||
mp_hal_delay_ms(ms);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms);
|
||||
|
||||
STATIC mp_obj_t time_sleep_us (mp_obj_t usec_in) {
|
||||
mp_int_t usec = mp_obj_get_int(usec_in);
|
||||
if (usec > 0) {
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
|
||||
|
||||
STATIC mp_obj_t time_ticks_ms(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
|
||||
|
||||
STATIC mp_obj_t time_ticks_us(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds() & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
|
||||
|
||||
STATIC mp_obj_t time_ticks_cpu(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
return MP_OBJ_NEW_SMALL_INT((SysTickPeriodGet() - SysTickValueGet()) & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
|
||||
|
||||
STATIC mp_obj_t time_ticks_diff(mp_obj_t t0, mp_obj_t t1) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
uint32_t start = mp_obj_get_int(t0);
|
||||
uint32_t end = mp_obj_get_int(t1);
|
||||
return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
|
||||
|
||||
STATIC const mp_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||
|
||||
@ -140,18 +184,18 @@ STATIC const mp_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
|
||||
|
||||
// MicroPython additions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&mp_utime_sleep_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&mp_utime_sleep_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&mp_utime_ticks_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&mp_utime_ticks_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&mp_utime_ticks_cpu_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_add), (mp_obj_t)&mp_utime_ticks_add_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&mp_utime_ticks_diff_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_utime = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_utime,
|
||||
.globals = (mp_obj_dict_t*)&time_module_globals,
|
||||
};
|
||||
|
||||
@ -26,5 +26,6 @@ STATIC MP_DEFINE_CONST_DICT(wipy_module_globals, wipy_module_globals_table);
|
||||
|
||||
const mp_obj_module_t wipy_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_wipy,
|
||||
.globals = (mp_obj_dict_t*)&wipy_module_globals,
|
||||
};
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "simplelink.h"
|
||||
#include "py/mpconfig.h"
|
||||
@ -35,11 +35,17 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "lib/netutils/netutils.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"
|
||||
#include "netutils.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modusocket.h"
|
||||
#include "modwlan.h"
|
||||
#include "pybioctl.h"
|
||||
#include "pybrtc.h"
|
||||
#include "debug.h"
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
@ -112,6 +118,26 @@ typedef enum{
|
||||
|
||||
#define ASSERT_ON_ERROR(x) ASSERT((x) >= 0)
|
||||
|
||||
#define IPV4_ADDR_STR_LEN_MAX (16)
|
||||
|
||||
#define WLAN_MAX_RX_SIZE 16000
|
||||
#define WLAN_MAX_TX_SIZE 1476
|
||||
|
||||
#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[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[5]; \
|
||||
ip[1] = addr.sa_data[4]; \
|
||||
ip[2] = addr.sa_data[3]; \
|
||||
ip[3] = addr.sa_data[2];
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
@ -136,9 +162,7 @@ STATIC const mp_irq_methods_t wlan_irq_methods;
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
#ifdef SL_PLATFORM_MULTI_THREADED
|
||||
OsiLockObj_t wlan_LockObj;
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
@ -373,18 +397,14 @@ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) {
|
||||
__attribute__ ((section (".boot")))
|
||||
void wlan_pre_init (void) {
|
||||
// create the wlan lock
|
||||
#ifdef SL_PLATFORM_MULTI_THREADED
|
||||
ASSERT(OSI_OK == sl_LockObjCreate(&wlan_LockObj, "WlanLock"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void wlan_first_start (void) {
|
||||
if (wlan_obj.mode < 0) {
|
||||
CLR_STATUS_BIT_ALL(wlan_obj.status);
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
#ifdef SL_PLATFORM_MULTI_THREADED
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
#endif
|
||||
}
|
||||
|
||||
// get the mac address
|
||||
@ -493,9 +513,7 @@ void wlan_update(void) {
|
||||
|
||||
void wlan_stop (uint32_t timeout) {
|
||||
wlan_servers_stop();
|
||||
#ifdef SL_PLATFORM_MULTI_THREADED
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
#endif
|
||||
sl_Stop(timeout);
|
||||
wlan_clear_data();
|
||||
wlan_obj.mode = -1;
|
||||
@ -551,15 +569,11 @@ STATIC void wlan_clear_data (void) {
|
||||
|
||||
STATIC void wlan_reenable (SlWlanMode_t mode) {
|
||||
// stop and start again
|
||||
#ifdef SL_PLATFORM_MULTI_THREADED
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
#endif
|
||||
sl_Stop(SL_STOP_TIMEOUT);
|
||||
wlan_clear_data();
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
#ifdef SL_PLATFORM_MULTI_THREADED
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
#endif
|
||||
ASSERT (wlan_obj.mode == mode);
|
||||
}
|
||||
|
||||
@ -589,7 +603,7 @@ STATIC void wlan_reset (void) {
|
||||
|
||||
STATIC void wlan_validate_mode (uint mode) {
|
||||
if (mode != ROLE_STA && mode != ROLE_AP) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@ -600,7 +614,7 @@ STATIC void wlan_set_mode (uint mode) {
|
||||
|
||||
STATIC void wlan_validate_ssid_len (uint32_t len) {
|
||||
if (len > MODWLAN_SSID_LEN_MAX) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@ -633,7 +647,7 @@ STATIC void wlan_validate_security (uint8_t auth, const char *key, uint8_t len)
|
||||
return;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len) {
|
||||
@ -656,7 +670,7 @@ STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len) {
|
||||
|
||||
STATIC void wlan_validate_channel (uint8_t channel) {
|
||||
if (channel < 1 || channel > 11) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@ -668,7 +682,7 @@ STATIC void wlan_set_channel (uint8_t channel) {
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
STATIC void wlan_validate_antenna (uint8_t antenna) {
|
||||
if (antenna != ANTENNA_TYPE_INTERNAL && antenna != ANTENNA_TYPE_EXTERNAL) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,7 +787,7 @@ STATIC mp_obj_t wlan_init_helper(wlan_obj_t *self, const mp_arg_val_t *args) {
|
||||
wlan_validate_mode(mode);
|
||||
|
||||
// get the ssid
|
||||
size_t ssid_len = 0;
|
||||
mp_uint_t ssid_len = 0;
|
||||
const char *ssid = NULL;
|
||||
if (args[1].u_obj != NULL) {
|
||||
ssid = mp_obj_str_get_data(args[1].u_obj, &ssid_len);
|
||||
@ -782,7 +796,7 @@ STATIC mp_obj_t wlan_init_helper(wlan_obj_t *self, const mp_arg_val_t *args) {
|
||||
|
||||
// get the auth config
|
||||
uint8_t auth = SL_SEC_TYPE_OPEN;
|
||||
size_t key_len = 0;
|
||||
mp_uint_t key_len = 0;
|
||||
const char *key = NULL;
|
||||
if (args[2].u_obj != mp_const_none) {
|
||||
mp_obj_t *sec;
|
||||
@ -797,9 +811,8 @@ STATIC mp_obj_t wlan_init_helper(wlan_obj_t *self, const mp_arg_val_t *args) {
|
||||
wlan_validate_channel(channel);
|
||||
|
||||
// get the antenna type
|
||||
uint8_t antenna = 0;
|
||||
uint8_t antenna = args[4].u_int;
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
antenna = args[4].u_int;
|
||||
wlan_validate_antenna(antenna);
|
||||
#endif
|
||||
|
||||
@ -815,11 +828,9 @@ STATIC const mp_arg_t wlan_init_args[] = {
|
||||
{ MP_QSTR_ssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_auth, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
{ MP_QSTR_antenna, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ANTENNA_TYPE_INTERNAL} },
|
||||
#endif
|
||||
};
|
||||
STATIC mp_obj_t wlan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t wlan_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -836,7 +847,7 @@ STATIC mp_obj_t wlan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
// start the peripheral
|
||||
wlan_init_helper(self, &args[1]);
|
||||
@ -860,7 +871,7 @@ STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
|
||||
|
||||
// check for correct wlan mode
|
||||
if (wlan_obj.mode == ROLE_AP) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
Sl_WlanNetworkEntry_t wlanEntry;
|
||||
@ -914,7 +925,7 @@ STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
|
||||
// check for the correct wlan mode
|
||||
if (wlan_obj.mode == ROLE_AP) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// parse args
|
||||
@ -922,13 +933,13 @@ STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// get the ssid
|
||||
size_t ssid_len;
|
||||
mp_uint_t ssid_len;
|
||||
const char *ssid = mp_obj_str_get_data(args[0].u_obj, &ssid_len);
|
||||
wlan_validate_ssid_len(ssid_len);
|
||||
|
||||
// get the auth config
|
||||
uint8_t auth = SL_SEC_TYPE_OPEN;
|
||||
size_t key_len = 0;
|
||||
mp_uint_t key_len = 0;
|
||||
const char *key = NULL;
|
||||
if (args[1].u_obj != mp_const_none) {
|
||||
mp_obj_t *sec;
|
||||
@ -962,9 +973,9 @@ STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
modwlan_Status_t status;
|
||||
status = wlan_do_connect (ssid, ssid_len, bssid, auth, key, key_len, timeout);
|
||||
if (status == MODWLAN_ERROR_TIMEOUT) {
|
||||
mp_raise_OSError(MP_ETIMEDOUT);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
} else if (status == MODWLAN_ERROR_INVALID_PARAMS) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -993,7 +1004,7 @@ STATIC mp_obj_t wlan_ifconfig (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
|
||||
|
||||
// check the interface id
|
||||
if (args[0].u_int != 0) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// get the configuration
|
||||
@ -1040,7 +1051,7 @@ STATIC mp_obj_t wlan_ifconfig (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
|
||||
// check for the correct string
|
||||
const char *mode = mp_obj_str_get_str(args[1].u_obj);
|
||||
if (strcmp("dhcp", mode)) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// only if we are not in AP mode
|
||||
@ -1077,7 +1088,7 @@ STATIC mp_obj_t wlan_ssid (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 1) {
|
||||
return mp_obj_new_str((const char *)self->ssid, strlen((const char *)self->ssid), false);
|
||||
} else {
|
||||
size_t len;
|
||||
mp_uint_t len;
|
||||
const char *ssid = mp_obj_str_get_data(args[1], &len);
|
||||
wlan_validate_ssid_len(len);
|
||||
wlan_set_ssid(ssid, len, false);
|
||||
@ -1101,7 +1112,7 @@ STATIC mp_obj_t wlan_auth (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
} else {
|
||||
// get the auth config
|
||||
uint8_t auth = SL_SEC_TYPE_OPEN;
|
||||
size_t key_len = 0;
|
||||
mp_uint_t key_len = 0;
|
||||
const char *key = NULL;
|
||||
if (args[1] != mp_const_none) {
|
||||
mp_obj_t *sec;
|
||||
@ -1154,7 +1165,7 @@ STATIC mp_obj_t wlan_mac (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
|
||||
if (bufinfo.len != 6) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
memcpy(self->mac, bufinfo.buf, SL_MAC_ADDR_LEN);
|
||||
sl_NetCfgSet(SL_MAC_ADDRESS_SET, 1, SL_MAC_ADDR_LEN, (_u8 *)self->mac);
|
||||
@ -1190,7 +1201,7 @@ STATIC mp_obj_t wlan_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
||||
return _irq;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
|
||||
|
||||
@ -1219,18 +1230,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
|
||||
//
|
||||
// // the call to sl_NetAppSet corrupts the input string URN=args[1], so we copy into a local buffer
|
||||
// if (len > MAX_DEVICE_URN_LEN) {
|
||||
// mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
// nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
// }
|
||||
// strcpy(urn, p);
|
||||
//
|
||||
// if (sl_NetAppSet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, len, (unsigned char *)urn) < 0) {
|
||||
// mp_raise_OSError(MP_EIO);
|
||||
// nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// // get the URN
|
||||
// if (sl_NetAppGet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, &len, (uint8_t *)urn) < 0) {
|
||||
// mp_raise_OSError(MP_EIO);
|
||||
// nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
// }
|
||||
// return mp_obj_new_str(urn, (len - 1), false);
|
||||
// }
|
||||
@ -1239,21 +1250,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
|
||||
//}
|
||||
//STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_urn_obj, 1, 2, wlan_urn);
|
||||
|
||||
STATIC mp_obj_t wlan_print_ver(void) {
|
||||
SlVersionFull ver;
|
||||
byte config_opt = SL_DEVICE_GENERAL_VERSION;
|
||||
byte config_len = sizeof(ver);
|
||||
sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &config_opt, &config_len, (byte*)&ver);
|
||||
printf("NWP: %d.%d.%d.%d\n", (int)ver.NwpVersion[0], (int)ver.NwpVersion[1], (int)ver.NwpVersion[2], (int)ver.NwpVersion[3]);
|
||||
printf("MAC: %d.%d.%d.%d\n", (int)ver.ChipFwAndPhyVersion.FwVersion[0], (int)ver.ChipFwAndPhyVersion.FwVersion[1],
|
||||
(int)ver.ChipFwAndPhyVersion.FwVersion[2], (int)ver.ChipFwAndPhyVersion.FwVersion[3]);
|
||||
printf("PHY: %d.%d.%d.%d\n", ver.ChipFwAndPhyVersion.PhyVersion[0], ver.ChipFwAndPhyVersion.PhyVersion[1],
|
||||
ver.ChipFwAndPhyVersion.PhyVersion[2], ver.ChipFwAndPhyVersion.PhyVersion[3]);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(wlan_print_ver_fun_obj, wlan_print_ver);
|
||||
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(wlan_print_ver_obj, MP_ROM_PTR(&wlan_print_ver_fun_obj));
|
||||
|
||||
STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&wlan_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&wlan_scan_obj },
|
||||
@ -1270,7 +1266,6 @@ STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_irq), (mp_obj_t)&wlan_irq_obj },
|
||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_connections), (mp_obj_t)&wlan_connections_obj },
|
||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_urn), (mp_obj_t)&wlan_urn_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_print_ver), (mp_obj_t)&wlan_print_ver_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STA), MP_OBJ_NEW_SMALL_INT(ROLE_STA) },
|
||||
@ -1278,10 +1273,8 @@ STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WEP), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WEP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WPA), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPA_WPA2) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WPA2), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPA_WPA2) },
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_ANT), MP_OBJ_NEW_SMALL_INT(ANTENNA_TYPE_INTERNAL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_EXT_ANT), MP_OBJ_NEW_SMALL_INT(ANTENNA_TYPE_EXTERNAL) },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ANY_EVENT), MP_OBJ_NEW_SMALL_INT(MODWLAN_WIFI_EVENT_ANY) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
|
||||
@ -1301,3 +1294,221 @@ STATIC const mp_irq_methods_t wlan_irq_methods = {
|
||||
.disable = wlan_lpds_irq_disable,
|
||||
.flags = wlan_irq_flags,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings; WLAN socket
|
||||
|
||||
int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family) {
|
||||
uint32_t ip;
|
||||
int result = sl_NetAppDnsGetHostByName((_i8 *)name, (_u16)len, (_u32*)&ip, (_u8)family);
|
||||
out_ip[0] = ip;
|
||||
out_ip[1] = ip >> 8;
|
||||
out_ip[2] = ip >> 16;
|
||||
out_ip[3] = ip >> 24;
|
||||
return result;
|
||||
}
|
||||
|
||||
int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno) {
|
||||
int16_t sd = sl_Socket(s->sock_base.u_param.domain, s->sock_base.u_param.type, s->sock_base.u_param.proto);
|
||||
if (sd < 0) {
|
||||
*_errno = sd;
|
||||
return -1;
|
||||
}
|
||||
s->sock_base.sd = sd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wlan_socket_close(mod_network_socket_obj_t *s) {
|
||||
// this is to prevent the finalizer to close a socket that failed when being created
|
||||
if (s->sock_base.sd >= 0) {
|
||||
modusocket_socket_delete(s->sock_base.sd);
|
||||
sl_Close(s->sock_base.sd);
|
||||
s->sock_base.sd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
|
||||
MAKE_SOCKADDR(addr, ip, port)
|
||||
int ret = sl_Bind(s->sock_base.sd, &addr, sizeof(addr));
|
||||
if (ret != 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wlan_socket_listen(mod_network_socket_obj_t *s, mp_int_t backlog, int *_errno) {
|
||||
int ret = sl_Listen(s->sock_base.sd, backlog);
|
||||
if (ret != 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2, byte *ip, mp_uint_t *port, int *_errno) {
|
||||
// accept incoming connection
|
||||
int16_t sd;
|
||||
sockaddr addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
|
||||
sd = sl_Accept(s->sock_base.sd, &addr, &addr_len);
|
||||
// save the socket descriptor
|
||||
s2->sock_base.sd = sd;
|
||||
if (sd < 0) {
|
||||
*_errno = sd;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// return ip and port
|
||||
UNPACK_SOCKADDR(addr, ip, *port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
|
||||
MAKE_SOCKADDR(addr, ip, port)
|
||||
int ret = sl_Connect(s->sock_base.sd, &addr, sizeof(addr));
|
||||
if (ret != 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno) {
|
||||
mp_int_t bytes = 0;
|
||||
if (len > 0) {
|
||||
bytes = sl_Send(s->sock_base.sd, (const void *)buf, len, 0);
|
||||
}
|
||||
if (bytes <= 0) {
|
||||
*_errno = bytes;
|
||||
return -1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno) {
|
||||
int ret = sl_Recv(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0);
|
||||
if (ret < 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) {
|
||||
MAKE_SOCKADDR(addr, ip, port)
|
||||
int ret = sl_SendTo(s->sock_base.sd, (byte*)buf, len, 0, (sockaddr*)&addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
|
||||
sockaddr addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
mp_int_t ret = sl_RecvFrom(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0, &addr, &addr_len);
|
||||
if (ret < 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
UNPACK_SOCKADDR(addr, ip, *port);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wlan_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) {
|
||||
int ret = sl_SetSockOpt(s->sock_base.sd, level, opt, optval, optlen);
|
||||
if (ret < 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int *_errno) {
|
||||
int ret;
|
||||
bool has_timeout;
|
||||
if (timeout_s == 0 || timeout_s == -1) {
|
||||
SlSockNonblocking_t option;
|
||||
if (timeout_s == 0) {
|
||||
// set non-blocking mode
|
||||
option.NonblockingEnabled = 1;
|
||||
} else {
|
||||
// set blocking mode
|
||||
option.NonblockingEnabled = 0;
|
||||
}
|
||||
ret = sl_SetSockOpt(s->sock_base.sd, SOL_SOCKET, SO_NONBLOCKING, &option, sizeof(option));
|
||||
has_timeout = false;
|
||||
} else {
|
||||
// set timeout
|
||||
struct SlTimeval_t timeVal;
|
||||
timeVal.tv_sec = timeout_s; // seconds
|
||||
timeVal.tv_usec = 0; // microseconds. 10000 microseconds resolution
|
||||
ret = sl_SetSockOpt(s->sock_base.sd, SOL_SOCKET, SO_RCVTIMEO, &timeVal, sizeof(timeVal));
|
||||
has_timeout = true;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
*_errno = ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->sock_base.has_timeout = has_timeout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t arg, int *_errno) {
|
||||
mp_int_t ret;
|
||||
if (request == MP_IOCTL_POLL) {
|
||||
mp_uint_t flags = arg;
|
||||
ret = 0;
|
||||
int32_t sd = s->sock_base.sd;
|
||||
|
||||
// init fds
|
||||
fd_set rfds, wfds, xfds;
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&xfds);
|
||||
|
||||
// set fds if needed
|
||||
if (flags & MP_IOCTL_POLL_RD) {
|
||||
FD_SET(sd, &rfds);
|
||||
}
|
||||
if (flags & MP_IOCTL_POLL_WR) {
|
||||
FD_SET(sd, &wfds);
|
||||
}
|
||||
if (flags & MP_IOCTL_POLL_HUP) {
|
||||
FD_SET(sd, &xfds);
|
||||
}
|
||||
|
||||
// call simplelink's select with minimum timeout
|
||||
SlTimeval_t tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1;
|
||||
int32_t nfds = sl_Select(sd + 1, &rfds, &wfds, &xfds, &tv);
|
||||
|
||||
// check for errors
|
||||
if (nfds == -1) {
|
||||
*_errno = nfds;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check return of select
|
||||
if (FD_ISSET(sd, &rfds)) {
|
||||
ret |= MP_IOCTL_POLL_RD;
|
||||
}
|
||||
if (FD_ISSET(sd, &wfds)) {
|
||||
ret |= MP_IOCTL_POLL_WR;
|
||||
}
|
||||
if (FD_ISSET(sd, &xfds)) {
|
||||
ret |= MP_IOCTL_POLL_HUP;
|
||||
}
|
||||
} else {
|
||||
*_errno = EINVAL;
|
||||
ret = MP_STREAM_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_MODWLAN_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_MODWLAN_H
|
||||
|
||||
#ifndef MODWLAN_H_
|
||||
#define MODWLAN_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
@ -96,4 +97,19 @@ extern bool wlan_is_connected (void);
|
||||
extern void wlan_set_current_time (uint32_t seconds_since_2000);
|
||||
extern void wlan_off_on (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_MODWLAN_H
|
||||
extern int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family);
|
||||
extern int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno);
|
||||
extern void wlan_socket_close(mod_network_socket_obj_t *s);
|
||||
extern int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno);
|
||||
extern int wlan_socket_listen(mod_network_socket_obj_t *s, mp_int_t backlog, int *_errno);
|
||||
extern int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2, byte *ip, mp_uint_t *port, int *_errno);
|
||||
extern int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno);
|
||||
extern int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno);
|
||||
extern int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno);
|
||||
extern int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno);
|
||||
extern int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno);
|
||||
extern int wlan_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno);
|
||||
extern int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int *_errno);
|
||||
extern int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t arg, int *_errno);
|
||||
|
||||
#endif /* MODWLAN_H_ */
|
||||
|
||||
@ -33,7 +33,6 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "bufhelper.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_adc.h"
|
||||
@ -105,7 +104,7 @@ STATIC void pyb_adc_init (pyb_adc_obj_t *self) {
|
||||
STATIC void pyb_adc_check_init(void) {
|
||||
// not initialized
|
||||
if (!pyb_adc_obj.enabled) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +140,7 @@ STATIC const mp_arg_t pyb_adc_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 12} },
|
||||
};
|
||||
STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -150,12 +149,12 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// check the number of bits
|
||||
if (args[1].u_int != 12) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// setup the object
|
||||
@ -174,7 +173,7 @@ STATIC mp_obj_t adc_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *k
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_adc_init_args[1], args);
|
||||
// check the number of bits
|
||||
if (args[0].u_int != 12) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
pyb_adc_init(pos_args[0]);
|
||||
return mp_const_none;
|
||||
@ -207,11 +206,11 @@ STATIC mp_obj_t adc_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t
|
||||
if (args[0].u_obj != MP_OBJ_NULL) {
|
||||
ch_id = mp_obj_get_int(args[0].u_obj);
|
||||
if (ch_id >= PYB_ADC_NUM_CHANNELS) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_os_resource_not_avaliable));
|
||||
} else if (args[1].u_obj != mp_const_none) {
|
||||
uint pin_ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0);
|
||||
if (ch_id != pin_ch_id) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -278,7 +277,7 @@ STATIC mp_obj_t adc_channel_value(mp_obj_t self_in) {
|
||||
|
||||
// the channel must be enabled
|
||||
if (!self->enabled) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// wait until a new value is available
|
||||
@ -290,7 +289,7 @@ STATIC mp_obj_t adc_channel_value(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_channel_value_obj, adc_channel_value);
|
||||
|
||||
STATIC mp_obj_t adc_channel_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t adc_channel_call(mp_obj_t self_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, 0, false);
|
||||
return adc_channel_value (self_in);
|
||||
}
|
||||
|
||||
@ -24,9 +24,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBADC_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBADC_H
|
||||
|
||||
#ifndef PYBADC_H_
|
||||
#define PYBADC_H_
|
||||
|
||||
extern const mp_obj_type_t pyb_adc_type;
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBADC_H
|
||||
#endif /* PYBADC_H_ */
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2017 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//#include <stdint.h>
|
||||
//#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
|
||||
#include "fatfs/src/drivers/sflash_diskio.h"
|
||||
#include "mods/pybflash.h"
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings to expose the internal flash as an object with the
|
||||
// block protocol.
|
||||
|
||||
// there is a singleton Flash object
|
||||
STATIC const mp_obj_base_t pyb_flash_obj = {&pyb_flash_type};
|
||||
|
||||
STATIC mp_obj_t pyb_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
|
||||
// return singleton object
|
||||
return (mp_obj_t)&pyb_flash_obj;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_flash_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||
DRESULT res = sflash_disk_read(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SFLASH_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_readblocks_obj, pyb_flash_readblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_flash_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
DRESULT res = sflash_disk_write(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SFLASH_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_writeblocks_obj, pyb_flash_writeblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_flash_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||
switch (cmd) {
|
||||
case BP_IOCTL_INIT: return MP_OBJ_NEW_SMALL_INT(sflash_disk_init() != RES_OK);
|
||||
case BP_IOCTL_DEINIT: sflash_disk_flush(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case BP_IOCTL_SYNC: sflash_disk_flush(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(SFLASH_SECTOR_COUNT);
|
||||
case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(SFLASH_SECTOR_SIZE);
|
||||
default: return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_ioctl_obj, pyb_flash_ioctl);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_flash_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_flash_readblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_flash_writeblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_flash_ioctl_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_flash_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Flash,
|
||||
.make_new = pyb_flash_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_flash_locals_dict,
|
||||
};
|
||||
|
||||
void pyb_flash_init_vfs(fs_user_mount_t *vfs) {
|
||||
vfs->base.type = &mp_fat_vfs_type;
|
||||
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
|
||||
vfs->fatfs.drv = vfs;
|
||||
vfs->readblocks[0] = (mp_obj_t)&pyb_flash_readblocks_obj;
|
||||
vfs->readblocks[1] = (mp_obj_t)&pyb_flash_obj;
|
||||
vfs->readblocks[2] = (mp_obj_t)sflash_disk_read; // native version
|
||||
vfs->writeblocks[0] = (mp_obj_t)&pyb_flash_writeblocks_obj;
|
||||
vfs->writeblocks[1] = (mp_obj_t)&pyb_flash_obj;
|
||||
vfs->writeblocks[2] = (mp_obj_t)sflash_disk_write; // native version
|
||||
vfs->u.ioctl[0] = (mp_obj_t)&pyb_flash_ioctl_obj;
|
||||
vfs->u.ioctl[1] = (mp_obj_t)&pyb_flash_obj;
|
||||
}
|
||||
@ -30,7 +30,6 @@
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "bufhelper.h"
|
||||
#include "inc/hw_types.h"
|
||||
@ -59,6 +58,8 @@ typedef struct _pyb_i2c_obj_t {
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBI2C_MASTER (0)
|
||||
|
||||
#define PYBI2C_MIN_BAUD_RATE_HZ (50000)
|
||||
#define PYBI2C_MAX_BAUD_RATE_HZ (400000)
|
||||
|
||||
@ -77,6 +78,7 @@ typedef struct _pyb_i2c_obj_t {
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_i2c_obj_t pyb_i2c_obj = {.baudrate = 0};
|
||||
STATIC const mp_obj_t pyb_i2c_def_pin[2] = {&pin_GP13, &pin_GP23};
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
@ -142,7 +144,7 @@ STATIC bool pyb_i2c_transaction(uint cmd) {
|
||||
STATIC void pyb_i2c_check_init(pyb_i2c_obj_t *self) {
|
||||
// not initialized
|
||||
if (!self->baudrate) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +256,7 @@ STATIC void pyb_i2c_read_into (mp_arg_val_t *args, vstr_t *vstr) {
|
||||
|
||||
// receive the data
|
||||
if (!pyb_i2c_read(args[0].u_int, (byte *)vstr->buf, vstr->len)) {
|
||||
mp_raise_OSError(MP_EIO);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,10 +275,8 @@ STATIC void pyb_i2c_readmem_into (mp_arg_val_t *args, vstr_t *vstr) {
|
||||
if (pyb_i2c_mem_addr_write (i2c_addr, (byte *)&mem_addr, mem_addr_size)) {
|
||||
// Read the specified length of data
|
||||
if (!pyb_i2c_read (i2c_addr, (byte *)vstr->buf, vstr->len)) {
|
||||
mp_raise_OSError(MP_EIO);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
} else {
|
||||
mp_raise_OSError(MP_EIO);
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,34 +286,33 @@ STATIC void pyb_i2c_readmem_into (mp_arg_val_t *args, vstr_t *vstr) {
|
||||
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) {
|
||||
mp_printf(print, "I2C(0, baudrate=%u)", self->baudrate);
|
||||
mp_printf(print, "I2C(0, I2C.MASTER, baudrate=%u)", self->baudrate);
|
||||
} else {
|
||||
mp_print_str(print, "I2C(0)");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_scl, ARG_sda, ARG_freq };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_scl, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_sda, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, const mp_arg_val_t *args) {
|
||||
// verify that mode is master
|
||||
if (args[0].u_int != PYBI2C_MASTER) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// make sure the baudrate is between the valid range
|
||||
self->baudrate = MIN(MAX(args[ARG_freq].u_int, PYBI2C_MIN_BAUD_RATE_HZ), PYBI2C_MAX_BAUD_RATE_HZ);
|
||||
self->baudrate = MIN(MAX(args[1].u_int, PYBI2C_MIN_BAUD_RATE_HZ), PYBI2C_MAX_BAUD_RATE_HZ);
|
||||
|
||||
// assign the pins
|
||||
mp_obj_t pins[2] = {&pin_GP13, &pin_GP23}; // default (SDA, SCL) pins
|
||||
if (args[ARG_scl].u_obj != MP_OBJ_NULL) {
|
||||
pins[1] = args[ARG_scl].u_obj;
|
||||
mp_obj_t pins_o = args[2].u_obj;
|
||||
if (pins_o != mp_const_none) {
|
||||
mp_obj_t *pins;
|
||||
if (pins_o == MP_OBJ_NULL) {
|
||||
// use the default pins
|
||||
pins = (mp_obj_t *)pyb_i2c_def_pin;
|
||||
} else {
|
||||
mp_obj_get_array_fixed_n(pins_o, 2, &pins);
|
||||
}
|
||||
pin_assign_pins_af (pins, 2, PIN_TYPE_STD_PU, PIN_FN_I2C, 0);
|
||||
}
|
||||
if (args[ARG_sda].u_obj != MP_OBJ_NULL) {
|
||||
pins[0] = args[ARG_sda].u_obj;
|
||||
}
|
||||
pin_assign_pins_af(pins, 2, PIN_TYPE_STD_PU, PIN_FN_I2C, 0);
|
||||
|
||||
// init the I2C bus
|
||||
i2c_init(self);
|
||||
@ -322,34 +321,44 @@ STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, size_t n_args, const mp
|
||||
pyb_sleep_add ((const mp_obj_t)self, (WakeUpCB_t)i2c_init);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
// check the id argument, if given
|
||||
if (n_args > 0) {
|
||||
if (all_args[0] != MP_OBJ_NEW_SMALL_INT(0)) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
}
|
||||
--n_args;
|
||||
++all_args;
|
||||
}
|
||||
|
||||
STATIC const mp_arg_t pyb_i2c_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = PYBI2C_MASTER} },
|
||||
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
|
||||
{ MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t pyb_i2c_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_init_args)];
|
||||
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_i2c_init_args, args);
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// setup the object
|
||||
pyb_i2c_obj_t *self = &pyb_i2c_obj;
|
||||
self->base.type = &pyb_i2c_type;
|
||||
|
||||
// start the peripheral
|
||||
pyb_i2c_init_helper(self, n_args, all_args, &kw_args);
|
||||
pyb_i2c_init_helper(self, &args[1]);
|
||||
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return pyb_i2c_init_helper(pos_args[0], n_args - 1, pos_args + 1, kw_args);
|
||||
STATIC mp_obj_t pyb_i2c_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_init_args) - 1];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_i2c_init_args[1], args);
|
||||
return pyb_i2c_init_helper(pos_args[0], args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_init_obj, 1, pyb_i2c_init);
|
||||
|
||||
@ -436,7 +445,7 @@ STATIC mp_obj_t pyb_i2c_writeto(mp_uint_t n_args, const mp_obj_t *pos_args, mp_m
|
||||
|
||||
// send the data
|
||||
if (!pyb_i2c_write(args[0].u_int, bufinfo.buf, bufinfo.len, args[2].u_bool)) {
|
||||
mp_raise_OSError(MP_EIO);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// return the number of bytes written
|
||||
@ -477,7 +486,7 @@ STATIC mp_obj_t pyb_i2c_readfrom_mem_into(mp_uint_t n_args, const mp_obj_t *pos_
|
||||
// get the buffer to read into
|
||||
vstr_t vstr;
|
||||
pyb_i2c_readmem_into (args, &vstr);
|
||||
return mp_const_none;
|
||||
return mp_obj_new_int(vstr.len);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_mem_into_obj, 1, pyb_i2c_readfrom_mem_into);
|
||||
|
||||
@ -501,10 +510,11 @@ STATIC mp_obj_t pyb_i2c_writeto_mem(mp_uint_t n_args, const mp_obj_t *pos_args,
|
||||
|
||||
// write the register address to write to.
|
||||
if (pyb_i2c_mem_write (i2c_addr, (byte *)&mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len)) {
|
||||
return mp_const_none;
|
||||
// return the number of bytes written
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
|
||||
mp_raise_OSError(MP_EIO);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_writeto_mem_obj, 1, pyb_i2c_writeto_mem);
|
||||
|
||||
@ -519,6 +529,9 @@ STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readfrom_mem), (mp_obj_t)&pyb_i2c_readfrom_mem_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readfrom_mem_into), (mp_obj_t)&pyb_i2c_readfrom_mem_into_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeto_mem), (mp_obj_t)&pyb_i2c_writeto_mem_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(PYBI2C_MASTER) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table);
|
||||
|
||||
@ -24,9 +24,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBI2C_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBI2C_H
|
||||
|
||||
#ifndef PYBI2C_H_
|
||||
#define PYBI2C_H_
|
||||
|
||||
extern const mp_obj_type_t pyb_i2c_type;
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBI2C_H
|
||||
#endif // PYBI2C_H_
|
||||
|
||||
@ -145,7 +145,7 @@ pin_obj_t *pin_find(mp_obj_t user_obj) {
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint strength) {
|
||||
@ -185,7 +185,7 @@ uint8_t pin_find_peripheral_unit (const mp_obj_t pin, uint8_t fn, uint8_t type)
|
||||
return pin_o->af_list[i].unit;
|
||||
}
|
||||
}
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit) {
|
||||
@ -195,13 +195,13 @@ uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit)
|
||||
return pin_o->af_list[i].type;
|
||||
}
|
||||
}
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) {
|
||||
int8_t af = pin_obj_find_af(pin, fn, unit, type);
|
||||
if (af < 0) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
return af;
|
||||
}
|
||||
@ -426,18 +426,18 @@ STATIC void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t prio
|
||||
STATIC void pin_validate_mode (uint mode) {
|
||||
if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT && mode != PIN_TYPE_OD &&
|
||||
mode != GPIO_DIR_MODE_ALT && mode != GPIO_DIR_MODE_ALT_OD) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
STATIC void pin_validate_pull (uint pull) {
|
||||
if (pull != PIN_TYPE_STD && pull != PIN_TYPE_STD_PU && pull != PIN_TYPE_STD_PD) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pin_validate_drive(uint strength) {
|
||||
if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,7 +450,7 @@ STATIC void pin_validate_af(const pin_obj_t* pin, int8_t idx, uint8_t *fn, uint8
|
||||
return;
|
||||
}
|
||||
}
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC uint8_t pin_get_value (const pin_obj_t* self) {
|
||||
@ -591,7 +591,7 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
@ -647,7 +647,7 @@ STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
|
||||
mp_printf(print, ", alt=%d)", alt);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
// Run an argument through the mapper and return the result.
|
||||
@ -684,6 +684,13 @@ STATIC mp_obj_t pin_value(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
|
||||
|
||||
STATIC mp_obj_t pin_toggle(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
MAP_GPIOPinWrite(self->port, self->bit, ~MAP_GPIOPinRead(self->port, self->bit));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_toggle_obj, pin_toggle);
|
||||
|
||||
STATIC mp_obj_t pin_id(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_QSTR(self->name);
|
||||
@ -740,7 +747,7 @@ STATIC mp_obj_t pin_drive(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_drive_obj, 1, 2, pin_drive);
|
||||
|
||||
STATIC mp_obj_t pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
mp_obj_t _args[2] = {self_in, *args};
|
||||
return pin_value (n_args + 1, _args);
|
||||
@ -898,7 +905,7 @@ STATIC mp_obj_t pin_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *k
|
||||
return _irq;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_irq_obj, 1, pin_irq);
|
||||
|
||||
@ -906,6 +913,7 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pin_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pin_value_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&pin_toggle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_id), (mp_obj_t)&pin_id_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mode), (mp_obj_t)&pin_mode_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pull), (mp_obj_t)&pin_pull_obj },
|
||||
|
||||
@ -24,8 +24,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBPIN_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBPIN_H
|
||||
|
||||
#ifndef PYBPIN_H_
|
||||
#define PYBPIN_H_
|
||||
|
||||
enum {
|
||||
PORT_A0 = GPIOA0_BASE,
|
||||
@ -137,4 +138,4 @@ uint8_t pin_find_peripheral_unit (const mp_obj_t pin, uint8_t fn, uint8_t type);
|
||||
uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit);
|
||||
int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type);;
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBPIN_H
|
||||
#endif // PYBPIN_H_
|
||||
|
||||
@ -25,11 +25,11 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@ -38,6 +38,7 @@
|
||||
#include "pybrtc.h"
|
||||
#include "mpirq.h"
|
||||
#include "pybsleep.h"
|
||||
#include "timeutils.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
@ -196,12 +197,12 @@ STATIC uint pyb_rtc_datetime_s_us(const mp_obj_t datetime, uint32_t *seconds) {
|
||||
|
||||
// set date and time
|
||||
mp_obj_t *items;
|
||||
size_t len;
|
||||
uint len;
|
||||
mp_obj_get_array(datetime, &len, &items);
|
||||
|
||||
// verify the tuple
|
||||
if (len < 3 || len > 8) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
tm.tm_year = mp_obj_get_int(items[0]);
|
||||
@ -284,7 +285,7 @@ STATIC const mp_arg_t pyb_rtc_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_datetime, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -293,7 +294,7 @@ STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// setup the object
|
||||
@ -361,7 +362,7 @@ STATIC mp_obj_t pyb_rtc_alarm (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
|
||||
|
||||
// check the alarm id
|
||||
if (args[0].u_int != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
uint32_t f_seconds;
|
||||
@ -370,7 +371,7 @@ STATIC mp_obj_t pyb_rtc_alarm (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
|
||||
if (MP_OBJ_IS_TYPE(args[1].u_obj, &mp_type_tuple)) { // datetime tuple given
|
||||
// repeat cannot be used with a datetime tuple
|
||||
if (repeat) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
f_mseconds = pyb_rtc_datetime_s_us (args[1].u_obj, &f_seconds) / 1000;
|
||||
} else { // then it must be an integer
|
||||
@ -396,7 +397,7 @@ STATIC mp_obj_t pyb_rtc_alarm_left (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
|
||||
// only alarm id 0 is available
|
||||
if (n_args > 1 && mp_obj_get_int(args[1]) != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// get the current time
|
||||
@ -414,7 +415,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_alarm_left_obj, 1, 2, pyb_rtc
|
||||
STATIC mp_obj_t pyb_rtc_alarm_cancel (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// only alarm id 0 is available
|
||||
if (n_args > 1 && mp_obj_get_int(args[1]) != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
// disable the alarm
|
||||
pyb_rtc_disable_alarm();
|
||||
@ -452,7 +453,7 @@ STATIC mp_obj_t pyb_rtc_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
return _irq;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_irq_obj, 1, pyb_rtc_irq);
|
||||
|
||||
|
||||
@ -24,8 +24,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBRTC_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBRTC_H
|
||||
|
||||
#ifndef PYBRTC_H_
|
||||
#define PYBRTC_H_
|
||||
|
||||
// RTC triggers
|
||||
#define PYB_RTC_ALARM0 (0x01)
|
||||
@ -55,4 +56,4 @@ extern void pyb_rtc_calc_future_time (uint32_t a_mseconds, uint32_t *f_seconds,
|
||||
extern void pyb_rtc_repeat_alarm (pyb_rtc_obj_t *self);
|
||||
extern void pyb_rtc_disable_alarm (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBRTC_H
|
||||
#endif // PYBRTC_H_
|
||||
|
||||
@ -27,10 +27,6 @@
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@ -40,6 +36,8 @@
|
||||
#include "prcm.h"
|
||||
#include "gpio.h"
|
||||
#include "sdhost.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "pybsd.h"
|
||||
#include "mpexception.h"
|
||||
@ -66,7 +64,7 @@ STATIC const mp_obj_t pyb_sd_def_pin[3] = {&pin_GP10, &pin_GP11, &pin_GP15};
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pyb_sd_hw_init (pybsd_obj_t *self);
|
||||
STATIC mp_obj_t pyb_sd_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
STATIC mp_obj_t pyb_sd_make_new (const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
@ -109,7 +107,7 @@ STATIC mp_obj_t pyb_sd_init_helper (pybsd_obj_t *self, const mp_arg_val_t *args)
|
||||
|
||||
pyb_sd_hw_init (self);
|
||||
if (sd_disk_init() != 0) {
|
||||
mp_raise_OSError(MP_EIO);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// register it with the sleep module
|
||||
@ -125,7 +123,7 @@ STATIC const mp_arg_t pyb_sd_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_pins, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t pyb_sd_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t pyb_sd_make_new (const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -134,7 +132,7 @@ STATIC mp_obj_t pyb_sd_make_new(const mp_obj_type_t *type, size_t n_args, size_t
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// setup and initialize the object
|
||||
@ -165,50 +163,9 @@ STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sd_deinit_obj, pyb_sd_deinit);
|
||||
|
||||
STATIC mp_obj_t pyb_sd_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||
DRESULT res = sd_disk_read(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SD_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_readblocks_obj, pyb_sd_readblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_sd_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
DRESULT res = sd_disk_write(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SD_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_writeblocks_obj, pyb_sd_writeblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_sd_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||
switch (cmd) {
|
||||
case BP_IOCTL_INIT:
|
||||
case BP_IOCTL_DEINIT:
|
||||
case BP_IOCTL_SYNC:
|
||||
// nothing to do
|
||||
return MP_OBJ_NEW_SMALL_INT(0); // success
|
||||
|
||||
case BP_IOCTL_SEC_COUNT:
|
||||
return MP_OBJ_NEW_SMALL_INT(sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512));
|
||||
|
||||
case BP_IOCTL_SEC_SIZE:
|
||||
return MP_OBJ_NEW_SMALL_INT(SD_SECTOR_SIZE);
|
||||
|
||||
default: // unknown command
|
||||
return MP_OBJ_NEW_SMALL_INT(-1); // error
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_ioctl_obj, pyb_sd_ioctl);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_sd_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_sd_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_sd_deinit_obj },
|
||||
// block device protocol
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_sd_readblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_sd_writeblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_sd_ioctl_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_sd_locals_dict, pyb_sd_locals_dict_table);
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBSD_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBSD_H
|
||||
#ifndef PYBSD_H_
|
||||
#define PYBSD_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC TYPES
|
||||
@ -41,4 +41,4 @@ typedef struct {
|
||||
extern pybsd_obj_t pybsd_obj;
|
||||
extern const mp_obj_type_t pyb_sd_type;
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBSD_H
|
||||
#endif // PYBSD_H_
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBSLEEP_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBSLEEP_H
|
||||
|
||||
#ifndef PYBSLEEP_H_
|
||||
#define PYBSLEEP_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
@ -69,4 +70,4 @@ void pyb_sleep_deepsleep (void);
|
||||
pybsleep_reset_cause_t pyb_sleep_get_reset_cause (void);
|
||||
pybsleep_wake_reason_t pyb_sleep_get_wake_reason (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBSLEEP_H
|
||||
#endif /* PYBSLEEP_H_ */
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "bufhelper.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_mcspi.h"
|
||||
@ -132,7 +131,7 @@ STATIC void pybspi_rx (pyb_spi_obj_t *self, void *data) {
|
||||
|
||||
STATIC void pybspi_transfer (pyb_spi_obj_t *self, const char *txdata, char *rxdata, uint32_t len, uint32_t *txchar) {
|
||||
if (!self->baudrate) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
// send and receive the data
|
||||
MAP_SPICSEnable(GSPI_BASE);
|
||||
@ -149,7 +148,7 @@ STATIC void pybspi_transfer (pyb_spi_obj_t *self, const char *txdata, char *rxda
|
||||
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) {
|
||||
mp_printf(print, "SPI(0, baudrate=%u, bits=%u, polarity=%u, phase=%u, firstbit=SPI.MSB)",
|
||||
mp_printf(print, "SPI(0, SPI.MASTER, baudrate=%u, bits=%u, polarity=%u, phase=%u, firstbit=SPI.MSB)",
|
||||
self->baudrate, (self->wlen * 8), self->polarity, self->phase);
|
||||
} else {
|
||||
mp_print_str(print, "SPI(0)");
|
||||
@ -157,8 +156,13 @@ STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, const mp_arg_val_t *args) {
|
||||
// verify that mode is master
|
||||
if (args[0].u_int != SPI_MODE_MASTER) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
uint bits;
|
||||
switch (args[1].u_int) {
|
||||
switch (args[2].u_int) {
|
||||
case 8:
|
||||
bits = SPI_WL_8;
|
||||
break;
|
||||
@ -173,27 +177,27 @@ STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, const mp_arg_val_t *arg
|
||||
break;
|
||||
}
|
||||
|
||||
uint polarity = args[2].u_int;
|
||||
uint phase = args[3].u_int;
|
||||
uint polarity = args[3].u_int;
|
||||
uint phase = args[4].u_int;
|
||||
if (polarity > 1 || phase > 1) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
uint firstbit = args[4].u_int;
|
||||
uint firstbit = args[5].u_int;
|
||||
if (firstbit != PYBSPI_FIRST_BIT_MSB) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// build the configuration
|
||||
self->baudrate = args[0].u_int;
|
||||
self->wlen = args[1].u_int >> 3;
|
||||
self->baudrate = args[1].u_int;
|
||||
self->wlen = args[2].u_int >> 3;
|
||||
self->config = bits | SPI_CS_ACTIVELOW | SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF;
|
||||
self->polarity = polarity;
|
||||
self->phase = phase;
|
||||
self->submode = (polarity << 1) | phase;
|
||||
|
||||
// assign the pins
|
||||
mp_obj_t pins_o = args[5].u_obj;
|
||||
mp_obj_t pins_o = args[6].u_obj;
|
||||
if (pins_o != mp_const_none) {
|
||||
mp_obj_t *pins;
|
||||
if (pins_o == MP_OBJ_NULL) {
|
||||
@ -214,11 +218,12 @@ STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, const mp_arg_val_t *arg
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
static const mp_arg_t pyb_spi_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = SPI_MODE_MASTER} },
|
||||
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000000} }, // 1MHz
|
||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
@ -226,7 +231,7 @@ static const mp_arg_t pyb_spi_init_args[] = {
|
||||
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYBSPI_FIRST_BIT_MSB} },
|
||||
{ MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -235,7 +240,7 @@ STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// setup the object
|
||||
@ -290,7 +295,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_write_obj, pyb_spi_write);
|
||||
STATIC mp_obj_t pyb_spi_read(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_nbytes, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_write, MP_ARG_INT, {.u_int = 0x00} },
|
||||
{ MP_QSTR_write, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x00} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
@ -314,7 +319,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_read_obj, 1, pyb_spi_read);
|
||||
STATIC mp_obj_t pyb_spi_readinto(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_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_write, MP_ARG_INT, {.u_int = 0x00} },
|
||||
{ MP_QSTR_write, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x00} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
@ -352,7 +357,7 @@ STATIC mp_obj_t pyb_spi_write_readinto (mp_obj_t self, mp_obj_t writebuf, mp_obj
|
||||
// get the read buffer
|
||||
mp_get_buffer_raise(readbuf, &bufinfo_read, MP_BUFFER_WRITE);
|
||||
if (bufinfo_read.len != bufinfo_write.len) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,6 +379,7 @@ STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write_readinto), (mp_obj_t)&pyb_spi_write_readinto_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(SPI_MODE_MASTER) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_MSB), MP_OBJ_NEW_SMALL_INT(PYBSPI_FIRST_BIT_MSB) },
|
||||
};
|
||||
|
||||
|
||||
@ -24,9 +24,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBSPI_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBSPI_H
|
||||
|
||||
#ifndef PYBSPI_H_
|
||||
#define PYBSPI_H_
|
||||
|
||||
extern const mp_obj_type_t pyb_spi_type;
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBSPI_H
|
||||
#endif // PYBSPI_H_
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@ -224,7 +223,7 @@ STATIC uint32_t compute_prescaler_period_and_match_value(pyb_timer_channel_obj_t
|
||||
return prescaler;
|
||||
|
||||
error:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC void timer_init (pyb_timer_obj_t *tim) {
|
||||
@ -320,17 +319,17 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *tim, mp_uint_t n_args, co
|
||||
return mp_const_none;
|
||||
|
||||
error:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
// create a new Timer object
|
||||
int32_t timer_idx = mp_obj_get_int(args[0]);
|
||||
if (timer_idx < 0 || timer_idx > (PYBTIMER_NUM_TIMERS - 1)) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
pyb_timer_obj_t *tim = &pyb_timer_obj[timer_idx];
|
||||
@ -371,7 +370,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
||||
|
||||
// verify that the timer has been already initialized
|
||||
if (!tim->config) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
if (channel_n != TIMER_A && channel_n != TIMER_B && channel_n != (TIMER_A | TIMER_B)) {
|
||||
// invalid channel
|
||||
@ -441,7 +440,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
||||
return ch;
|
||||
|
||||
error:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_obj, 2, pyb_timer_channel);
|
||||
|
||||
@ -561,7 +560,7 @@ STATIC mp_obj_t pyb_timer_channel_freq(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// set
|
||||
int32_t _frequency = mp_obj_get_int(args[1]);
|
||||
if (_frequency <= 0) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
ch->frequency = _frequency;
|
||||
ch->period = 1000000 / _frequency;
|
||||
@ -580,7 +579,7 @@ STATIC mp_obj_t pyb_timer_channel_period(mp_uint_t n_args, const mp_obj_t *args)
|
||||
// set
|
||||
int32_t _period = mp_obj_get_int(args[1]);
|
||||
if (_period <= 0) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
ch->period = _period;
|
||||
ch->frequency = 1000000 / _period;
|
||||
@ -713,7 +712,7 @@ STATIC mp_obj_t pyb_timer_channel_irq (mp_uint_t n_args, const mp_obj_t *pos_arg
|
||||
return _irq;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_irq_obj, 1, pyb_timer_channel_irq);
|
||||
|
||||
|
||||
@ -24,8 +24,6 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBTIMER_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBTIMER_H
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED DATA
|
||||
@ -37,4 +35,3 @@ extern const mp_obj_type_t pyb_timer_type;
|
||||
******************************************************************************/
|
||||
void timer_init0 (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBTIMER_H
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "uart.h"
|
||||
#include "pybuart.h"
|
||||
#include "mpirq.h"
|
||||
#include "pybioctl.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpexception.h"
|
||||
#include "py/mpstate.h"
|
||||
@ -279,7 +280,7 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) {
|
||||
STATIC void uart_check_init(pyb_uart_obj_t *self) {
|
||||
// not initialized
|
||||
if (!self->baudrate) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,13 +376,10 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *a
|
||||
config |= UART_CONFIG_PAR_NONE;
|
||||
} else {
|
||||
uint parity = mp_obj_get_int(args[2].u_obj);
|
||||
if (parity == 0) {
|
||||
config |= UART_CONFIG_PAR_EVEN;
|
||||
} else if (parity == 1) {
|
||||
config |= UART_CONFIG_PAR_ODD;
|
||||
} else {
|
||||
if (parity != UART_CONFIG_PAR_ODD && parity != UART_CONFIG_PAR_EVEN) {
|
||||
goto error;
|
||||
}
|
||||
config |= parity;
|
||||
}
|
||||
// stop bits
|
||||
config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO);
|
||||
@ -391,7 +389,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *a
|
||||
uint flowcontrol = UART_FLOWCONTROL_NONE;
|
||||
if (pins_o != mp_const_none) {
|
||||
mp_obj_t *pins;
|
||||
size_t n_pins = 2;
|
||||
mp_uint_t n_pins = 2;
|
||||
if (pins_o == MP_OBJ_NULL) {
|
||||
// use the default pins
|
||||
pins = (mp_obj_t *)pyb_uart_def_pin[self->uart_id];
|
||||
@ -434,7 +432,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *a
|
||||
return mp_const_none;
|
||||
|
||||
error:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC const mp_arg_t pyb_uart_init_args[] = {
|
||||
@ -445,7 +443,7 @@ STATIC const mp_arg_t pyb_uart_init_args[] = {
|
||||
{ MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
|
||||
{ MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -457,7 +455,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
|
||||
if (args[0].u_obj == MP_OBJ_NULL) {
|
||||
if (args[5].u_obj != MP_OBJ_NULL) {
|
||||
mp_obj_t *pins;
|
||||
size_t n_pins = 2;
|
||||
mp_uint_t n_pins = 2;
|
||||
mp_obj_get_array(args[5].u_obj, &n_pins, &pins);
|
||||
// check the Tx pin (or the Rx if Tx is None)
|
||||
if (pins[0] == mp_const_none) {
|
||||
@ -474,7 +472,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
|
||||
}
|
||||
|
||||
if (uart_id > PYB_UART_1) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// get the correct uart instance
|
||||
@ -558,7 +556,7 @@ STATIC mp_obj_t pyb_uart_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
return uart_irq_new (self, trigger, priority, args[2].u_obj);
|
||||
|
||||
invalid_args:
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq);
|
||||
|
||||
@ -572,6 +570,8 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
|
||||
|
||||
/// \method read([nbytes])
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
|
||||
/// \method readall()
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
|
||||
/// \method readline()
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
|
||||
/// \method readinto(buf[, nbytes])
|
||||
@ -580,6 +580,8 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_EVEN), MP_OBJ_NEW_SMALL_INT(UART_CONFIG_PAR_EVEN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ODD), MP_OBJ_NEW_SMALL_INT(UART_CONFIG_PAR_ODD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RX_ANY), MP_OBJ_NEW_SMALL_INT(UART_TRIGGER_RX_ANY) },
|
||||
};
|
||||
|
||||
@ -597,8 +599,8 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
|
||||
|
||||
// wait for first char to become available
|
||||
if (!uart_rx_wait(self)) {
|
||||
// return MP_EAGAIN error to indicate non-blocking (then read() method returns None)
|
||||
*errcode = MP_EAGAIN;
|
||||
// return EAGAIN error to indicate non-blocking (then read() method returns None)
|
||||
*errcode = EAGAIN;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
|
||||
@ -620,7 +622,7 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t
|
||||
|
||||
// write the data
|
||||
if (!uart_tx_strn(self, buf, size)) {
|
||||
mp_raise_OSError(MP_EIO);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@ -630,17 +632,17 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t a
|
||||
mp_uint_t ret;
|
||||
uart_check_init(self);
|
||||
|
||||
if (request == MP_STREAM_POLL) {
|
||||
if (request == MP_IOCTL_POLL) {
|
||||
mp_uint_t flags = arg;
|
||||
ret = 0;
|
||||
if ((flags & MP_STREAM_POLL_RD) && uart_rx_any(self)) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
if ((flags & MP_IOCTL_POLL_RD) && uart_rx_any(self)) {
|
||||
ret |= MP_IOCTL_POLL_RD;
|
||||
}
|
||||
if ((flags & MP_STREAM_POLL_WR) && MAP_UARTSpaceAvail(self->reg)) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
if ((flags & MP_IOCTL_POLL_WR) && MAP_UARTSpaceAvail(self->reg)) {
|
||||
ret |= MP_IOCTL_POLL_WR;
|
||||
}
|
||||
} else {
|
||||
*errcode = MP_EINVAL;
|
||||
*errcode = EINVAL;
|
||||
ret = MP_STREAM_ERROR;
|
||||
}
|
||||
return ret;
|
||||
@ -665,7 +667,7 @@ const mp_obj_type_t pyb_uart_type = {
|
||||
.name = MP_QSTR_UART,
|
||||
.print = pyb_uart_print,
|
||||
.make_new = pyb_uart_make_new,
|
||||
.getiter = mp_identity_getiter,
|
||||
.getiter = mp_identity,
|
||||
.iternext = mp_stream_unbuffered_iter,
|
||||
.protocol = &uart_stream_p,
|
||||
.locals_dict = (mp_obj_t)&pyb_uart_locals_dict,
|
||||
|
||||
@ -24,8 +24,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBUART_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBUART_H
|
||||
|
||||
#ifndef PYBUART_H_
|
||||
#define PYBUART_H_
|
||||
|
||||
typedef enum {
|
||||
PYB_UART_0 = 0,
|
||||
@ -42,4 +43,4 @@ int uart_rx_char(pyb_uart_obj_t *uart_obj);
|
||||
bool uart_tx_char(pyb_uart_obj_t *self, int c);
|
||||
bool uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBUART_H
|
||||
#endif // PYBUART_H_
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
@ -93,7 +92,7 @@ STATIC const mp_arg_t pyb_wdt_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_timeout, MP_ARG_INT, {.u_int = 5000} }, // 5 s
|
||||
};
|
||||
STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// check the arguments
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
@ -101,14 +100,14 @@ STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
||||
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_wdt_init_args, args);
|
||||
|
||||
if (args[0].u_obj != mp_const_none && mp_obj_get_int(args[0].u_obj) > 0) {
|
||||
mp_raise_OSError(MP_ENODEV);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
uint timeout_ms = args[1].u_int;
|
||||
if (timeout_ms < PYBWDT_MIN_TIMEOUT_MS) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
if (pyb_wdt_obj.running) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// Enable the WDT peripheral clock
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBWDT_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBWDT_H
|
||||
|
||||
#ifndef PYBWDT_H_
|
||||
#define PYBWDT_H_
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
@ -35,4 +36,4 @@ void pybwdt_srv_alive (void);
|
||||
void pybwdt_srv_sleeping (bool state);
|
||||
void pybwdt_sl_alive (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBWDT_H
|
||||
#endif /* PYBWDT_H_ */
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDED_MPCONFIGPORT_H
|
||||
#define __INCLUDED_MPCONFIGPORT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
@ -35,7 +38,6 @@
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_ALLOC_PATH_MAX (128)
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (1)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_COMP_MODULE_CONST (1)
|
||||
@ -52,7 +54,6 @@
|
||||
#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_READER_VFS (1)
|
||||
#ifndef DEBUG // we need ram on the launchxl while debugging
|
||||
#define MICROPY_CPYTHON_COMPAT (1)
|
||||
#else
|
||||
@ -65,21 +66,18 @@
|
||||
#define MICROPY_FATFS_MAX_LFN (MICROPY_ALLOC_PATH_MAX)
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) // 1=SFN/ANSI 437=LFN/U.S.(OEM)
|
||||
#define MICROPY_FATFS_RPATH (2)
|
||||
#define MICROPY_FATFS_VOLUMES (2)
|
||||
#define MICROPY_FATFS_REENTRANT (1)
|
||||
#define MICROPY_FATFS_TIMEOUT (2500)
|
||||
#define MICROPY_FATFS_SYNC_T SemaphoreHandle_t
|
||||
#define MICROPY_FSUSERMOUNT_ADHOC (1)
|
||||
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_USE_INTERNAL_ERRNO (1)
|
||||
#define MICROPY_VFS (1)
|
||||
#define MICROPY_VFS_FAT (1)
|
||||
#define MICROPY_PY_ASYNC_AWAIT (0)
|
||||
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (1)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
|
||||
#define MICROPY_PY_BUILTINS_INPUT (1)
|
||||
#define MICROPY_PY_BUILTINS_HELP (1)
|
||||
#define MICROPY_PY_BUILTINS_HELP_TEXT cc3200_help_text
|
||||
#ifndef DEBUG
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
|
||||
@ -104,8 +102,6 @@
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (1)
|
||||
#define MICROPY_PY_IO_FILEIO (1)
|
||||
#define MICROPY_PY_UERRNO (1)
|
||||
#define MICROPY_PY_UERRNO_ERRORCODE (0)
|
||||
#define MICROPY_PY_THREAD (1)
|
||||
#define MICROPY_PY_THREAD_GIL (1)
|
||||
#define MICROPY_PY_UBINASCII (0)
|
||||
@ -115,31 +111,14 @@
|
||||
#define MICROPY_PY_URE (1)
|
||||
#define MICROPY_PY_UHEAPQ (0)
|
||||
#define MICROPY_PY_UHASHLIB (0)
|
||||
#define MICROPY_PY_USELECT (1)
|
||||
#define MICROPY_PY_UTIME_MP_HAL (1)
|
||||
|
||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
|
||||
|
||||
// We define our own list of errno constants to include in uerrno module
|
||||
#define MICROPY_PY_UERRNO_LIST \
|
||||
X(EPERM) \
|
||||
X(EIO) \
|
||||
X(ENODEV) \
|
||||
X(EINVAL) \
|
||||
X(ETIMEDOUT) \
|
||||
|
||||
// TODO these should be generic, not bound to fatfs
|
||||
#define mp_type_fileio fatfs_type_fileio
|
||||
#define mp_type_textio fatfs_type_textio
|
||||
|
||||
// use vfs's functions for import stat and builtin open
|
||||
#define mp_import_stat mp_vfs_import_stat
|
||||
#define mp_builtin_open mp_vfs_open
|
||||
#define mp_builtin_open_obj mp_vfs_open_obj
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, \
|
||||
|
||||
// extra built in modules to add to the list of known ones
|
||||
@ -167,7 +146,6 @@ extern const struct _mp_obj_module_t mp_module_ussl;
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ussl), (mp_obj_t)&mp_module_ussl }, \
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_errno), (mp_obj_t)&mp_module_uerrno }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_ustruct }, \
|
||||
{ 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 }, \
|
||||
@ -192,11 +170,13 @@ extern const struct _mp_obj_module_t mp_module_ussl;
|
||||
mp_obj_list_t pyb_sleep_obj_list; \
|
||||
mp_obj_list_t mp_irq_obj_list; \
|
||||
mp_obj_list_t pyb_timer_channel_obj_list; \
|
||||
mp_obj_list_t mount_obj_list; \
|
||||
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \
|
||||
struct _os_term_dup_obj_t *os_term_dup_obj; \
|
||||
|
||||
|
||||
// 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)
|
||||
|
||||
@ -211,7 +191,6 @@ typedef long mp_off_t;
|
||||
|
||||
#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
|
||||
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
|
||||
#define MICROPY_EVENT_POLL_HOOK __WFI();
|
||||
|
||||
// assembly functions to handle critical sections, interrupt
|
||||
// disabling/enabling and sleep mode enter/exit
|
||||
@ -232,3 +211,5 @@ typedef long mp_off_t;
|
||||
#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
|
||||
|
||||
@ -33,11 +33,6 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/mp-readline/readline.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@ -52,6 +47,7 @@
|
||||
#include "lib/utils/pyexec.h"
|
||||
#include "gccollect.h"
|
||||
#include "gchelper.h"
|
||||
#include "readline.h"
|
||||
#include "mperror.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
@ -60,12 +56,13 @@
|
||||
#include "serverstask.h"
|
||||
#include "telnet.h"
|
||||
#include "debug.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "mpexception.h"
|
||||
#include "random.h"
|
||||
#include "pybi2c.h"
|
||||
#include "pins.h"
|
||||
#include "mods/pybflash.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybtimer.h"
|
||||
#include "cryptohash.h"
|
||||
@ -97,22 +94,17 @@ OsiTaskHandle svTaskHandle;
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static fs_user_mount_t *sflash_vfs_fat;
|
||||
static FATFS *sflash_fatfs;
|
||||
|
||||
static const char fresh_main_py[] = "# main.py -- put your code here!\r\n";
|
||||
static const char fresh_boot_py[] = "# boot.py -- run on boot-up\r\n"
|
||||
"# can run arbitrary Python, but best to keep it minimal\r\n"
|
||||
#if MICROPY_STDIO_UART
|
||||
"import os, machine\r\n"
|
||||
"os.dupterm(machine.UART(0, " MP_STRINGIFY(MICROPY_STDIO_UART_BAUD) "))\r\n"
|
||||
#endif
|
||||
;
|
||||
"# can run arbitrary Python, but best to keep it minimal\r\n";
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
void TASK_MicroPython (void *pvParameters) {
|
||||
void TASK_Micropython (void *pvParameters) {
|
||||
// get the top of the stack to initialize the garbage collector
|
||||
uint32_t sp = gc_helper_get_sp();
|
||||
|
||||
@ -152,6 +144,7 @@ soft_reset:
|
||||
timer_init0();
|
||||
readline_init0();
|
||||
mod_network_init0();
|
||||
moduos_init0();
|
||||
rng_init0();
|
||||
|
||||
pybsleep_reset_cause_t rstcause = pyb_sleep_get_reset_cause();
|
||||
@ -272,7 +265,7 @@ STATIC void mptask_pre_init (void) {
|
||||
ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY));
|
||||
|
||||
// Allocate memory for the flash file system
|
||||
ASSERT ((sflash_vfs_fat = mem_Malloc(sizeof(*sflash_vfs_fat))) != NULL);
|
||||
ASSERT ((sflash_fatfs = mem_Malloc(sizeof(FATFS))) != NULL);
|
||||
|
||||
// this one allocates memory for the nvic vault
|
||||
pyb_sleep_pre_init();
|
||||
@ -298,19 +291,17 @@ 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.
|
||||
// init the vfs object
|
||||
fs_user_mount_t *vfs_fat = sflash_vfs_fat;
|
||||
vfs_fat->flags = 0;
|
||||
pyb_flash_init_vfs(vfs_fat);
|
||||
|
||||
// Create it if needed, and mount in on /flash.
|
||||
FRESULT res = f_mount(&vfs_fat->fatfs);
|
||||
FRESULT res = f_mount(sflash_fatfs, "/flash", 1);
|
||||
if (res == FR_NO_FILESYSTEM) {
|
||||
// no filesystem, so create a fresh one
|
||||
uint8_t working_buf[_MAX_SS];
|
||||
res = f_mkfs(&vfs_fat->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||
res = f_mkfs("/flash", 1, 0);
|
||||
if (res == FR_OK) {
|
||||
// success creating fresh LFS
|
||||
} else {
|
||||
@ -320,46 +311,33 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
mptask_create_main_py();
|
||||
} else if (res == FR_OK) {
|
||||
// mount sucessful
|
||||
if (FR_OK != f_stat(&vfs_fat->fatfs, "/main.py", &fno)) {
|
||||
if (FR_OK != f_stat("/flash/main.py", &fno)) {
|
||||
// create empty main.py
|
||||
mptask_create_main_py();
|
||||
}
|
||||
} else {
|
||||
fail:
|
||||
__fatal_error("failed to create /flash");
|
||||
}
|
||||
|
||||
// mount the flash device (there should be no other devices mounted at this point)
|
||||
// we allocate this structure on the heap because vfs->next is a root pointer
|
||||
mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
|
||||
if (vfs == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
vfs->str = "/flash";
|
||||
vfs->len = 6;
|
||||
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
|
||||
vfs->next = NULL;
|
||||
MP_STATE_VM(vfs_mount_table) = vfs;
|
||||
|
||||
// The current directory is used as the boot up directory.
|
||||
// It is set to the internal flash filesystem by default.
|
||||
MP_STATE_PORT(vfs_cur) = vfs;
|
||||
f_chdrive("/flash");
|
||||
|
||||
// create /flash/sys, /flash/lib and /flash/cert if they don't exist
|
||||
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/sys")) {
|
||||
f_mkdir(&vfs_fat->fatfs, "/sys");
|
||||
if (FR_OK != f_chdir ("/flash/sys")) {
|
||||
f_mkdir("/flash/sys");
|
||||
}
|
||||
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/lib")) {
|
||||
f_mkdir(&vfs_fat->fatfs, "/lib");
|
||||
if (FR_OK != f_chdir ("/flash/lib")) {
|
||||
f_mkdir("/flash/lib");
|
||||
}
|
||||
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/cert")) {
|
||||
f_mkdir(&vfs_fat->fatfs, "/cert");
|
||||
if (FR_OK != f_chdir ("/flash/cert")) {
|
||||
f_mkdir("/flash/cert");
|
||||
}
|
||||
|
||||
f_chdir(&vfs_fat->fatfs, "/");
|
||||
f_chdir ("/flash");
|
||||
|
||||
// make sure we have a /flash/boot.py. Create it if needed.
|
||||
res = f_stat(&vfs_fat->fatfs, "/boot.py", &fno);
|
||||
res = f_stat("/flash/boot.py", &fno);
|
||||
if (res == FR_OK) {
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
// exists as a directory
|
||||
@ -371,7 +349,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
} else {
|
||||
// doesn't exist, create fresh file
|
||||
FIL fp;
|
||||
f_open(&vfs_fat->fatfs, &fp, "/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
|
||||
@ -391,8 +369,9 @@ STATIC void mptask_enter_ap_mode (void) {
|
||||
STATIC void mptask_create_main_py (void) {
|
||||
// create empty main.py
|
||||
FIL fp;
|
||||
f_open(&sflash_vfs_fat->fatfs, &fp, "/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);
|
||||
}
|
||||
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MPTASK_H
|
||||
#define MICROPY_INCLUDED_CC3200_MPTASK_H
|
||||
|
||||
#ifndef MPTASK_H_
|
||||
#define MPTASK_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
@ -41,6 +42,6 @@ extern StackType_t mpTaskStack[];
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
extern void TASK_MicroPython (void *pvParameters);
|
||||
extern void TASK_Micropython (void *pvParameters);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MPTASK_H
|
||||
#endif /* MPTASK_H_ */
|
||||
|
||||
@ -28,13 +28,10 @@
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mpthread.h"
|
||||
#include "py/mphal.h"
|
||||
#include "mptask.h"
|
||||
#include "task.h"
|
||||
#include "irq.h"
|
||||
|
||||
#if MICROPY_PY_THREAD
|
||||
|
||||
@ -134,7 +131,7 @@ void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
|
||||
TaskHandle_t id = xTaskCreateStatic(freertos_entry, "Thread", *stack_size / sizeof(void*), arg, 2, stack, tcb);
|
||||
if (id == NULL) {
|
||||
mp_thread_mutex_unlock(&thread_mutex);
|
||||
mp_raise_msg(&mp_type_OSError, "can't create thread");
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't create thread"));
|
||||
}
|
||||
|
||||
// add thread to linked list of all threads
|
||||
@ -168,23 +165,14 @@ void mp_thread_mutex_init(mp_thread_mutex_t *mutex) {
|
||||
mutex->handle = xSemaphoreCreateMutexStatic(&mutex->buffer);
|
||||
}
|
||||
|
||||
// To allow hard interrupts to work with threading we only take/give the semaphore
|
||||
// if we are not within an interrupt context and interrupts are enabled.
|
||||
|
||||
int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) {
|
||||
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
||||
int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
|
||||
return ret == pdTRUE;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
|
||||
return ret == pdTRUE;
|
||||
}
|
||||
|
||||
void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
|
||||
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
||||
xSemaphoreGive(mutex->handle);
|
||||
// TODO check return value
|
||||
}
|
||||
xSemaphoreGive(mutex->handle);
|
||||
// TODO check return value
|
||||
}
|
||||
|
||||
#endif // MICROPY_PY_THREAD
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __MICROPY_INCLUDED_CC3200_MPTHREADPORT_H__
|
||||
#define __MICROPY_INCLUDED_CC3200_MPTHREADPORT_H__
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
#include "FreeRTOS.h"
|
||||
@ -37,3 +39,5 @@ typedef struct _mp_thread_mutex_t {
|
||||
|
||||
void mp_thread_init(void);
|
||||
void mp_thread_gc_others(void);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_CC3200_MPTHREADPORT_H__
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/misc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/mphal.h"
|
||||
#include "serverstask.h"
|
||||
#include "simplelink.h"
|
||||
@ -187,7 +187,7 @@ void servers_close_socket (int16_t *sd) {
|
||||
|
||||
void servers_set_login (char *user, char *pass) {
|
||||
if (strlen(user) > SERVERS_USER_PASS_LEN_MAX || strlen(pass) > SERVERS_USER_PASS_LEN_MAX) {
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
memcpy(servers_user, user, SERVERS_USER_PASS_LEN_MAX);
|
||||
memcpy(servers_pass, pass, SERVERS_USER_PASS_LEN_MAX);
|
||||
@ -196,7 +196,7 @@ void servers_set_login (char *user, char *pass) {
|
||||
void servers_set_timeout (uint32_t timeout) {
|
||||
if (timeout < SERVERS_MIN_TIMEOUT_MS) {
|
||||
// timeout is too low
|
||||
mp_raise_ValueError(mpexception_value_invalid_arguments);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
servers_data.timeout = timeout;
|
||||
}
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_SERVERSTASK_H
|
||||
#define MICROPY_INCLUDED_CC3200_SERVERSTASK_H
|
||||
|
||||
#ifndef SERVERSTASK_H_
|
||||
#define SERVERSTASK_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
@ -72,4 +73,4 @@ extern void server_sleep_sockets (void);
|
||||
extern void servers_set_timeout (uint32_t timeout);
|
||||
extern uint32_t servers_get_timeout (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_SERVERSTASK_H
|
||||
#endif /* SERVERSTASK_H_ */
|
||||
|
||||
@ -163,7 +163,7 @@ extern "C" {
|
||||
|
||||
\warning
|
||||
*/
|
||||
/* #define SL_INC_STD_BSD_API_NAMING */
|
||||
#define SL_INC_STD_BSD_API_NAMING
|
||||
|
||||
|
||||
/*!
|
||||
|
||||
@ -296,23 +296,23 @@ static void telnet_wait_for_enabled (void) {
|
||||
|
||||
static bool telnet_create_socket (void) {
|
||||
SlSockNonblocking_t nonBlockingOption;
|
||||
SlSockAddrIn_t sServerAddress;
|
||||
sockaddr_in sServerAddress;
|
||||
_i16 result;
|
||||
|
||||
// Open a socket for telnet
|
||||
ASSERT ((telnet_data.sd = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_IPPROTO_TCP)) > 0);
|
||||
ASSERT ((telnet_data.sd = sl_Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) > 0);
|
||||
if (telnet_data.sd > 0) {
|
||||
// add the socket to the network administration
|
||||
modusocket_socket_add(telnet_data.sd, false);
|
||||
|
||||
// Enable non-blocking mode
|
||||
nonBlockingOption.NonblockingEnabled = 1;
|
||||
ASSERT ((result = sl_SetSockOpt(telnet_data.sd, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption))) == SL_SOC_OK);
|
||||
ASSERT ((result = sl_SetSockOpt(telnet_data.sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption))) == SL_SOC_OK);
|
||||
|
||||
// Bind the socket to a port number
|
||||
sServerAddress.sin_family = SL_AF_INET;
|
||||
sServerAddress.sin_addr.s_addr = SL_INADDR_ANY;
|
||||
sServerAddress.sin_port = sl_Htons(TELNET_PORT);
|
||||
sServerAddress.sin_family = AF_INET;
|
||||
sServerAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
sServerAddress.sin_port = htons(TELNET_PORT);
|
||||
|
||||
ASSERT ((result |= sl_Bind(telnet_data.sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress))) == SL_SOC_OK);
|
||||
|
||||
@ -330,7 +330,7 @@ static bool telnet_create_socket (void) {
|
||||
|
||||
static void telnet_wait_for_connection (void) {
|
||||
SlSocklen_t in_addrSize;
|
||||
SlSockAddrIn_t sClientAddress;
|
||||
sockaddr_in sClientAddress;
|
||||
|
||||
// accepts a connection from a TCP client, if there is any, otherwise returns SL_EAGAIN
|
||||
telnet_data.n_sd = sl_Accept(telnet_data.sd, (SlSockAddr_t *)&sClientAddress, (SlSocklen_t *)&in_addrSize);
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_TELNET_TELNET_H
|
||||
#define MICROPY_INCLUDED_CC3200_TELNET_TELNET_H
|
||||
|
||||
#ifndef TELNET_H_
|
||||
#define TELNET_H_
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED FUNCTIONS
|
||||
@ -38,4 +39,4 @@ extern void telnet_enable (void);
|
||||
extern void telnet_disable (void);
|
||||
extern void telnet_reset (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_TELNET_TELNET_H
|
||||
#endif /* TELNET_H_ */
|
||||
|
||||
@ -51,7 +51,7 @@ n_w = f.write(test_bytes)
|
||||
print(n_w == len(test_bytes))
|
||||
f.close()
|
||||
f = open('test.txt', 'r')
|
||||
r = bytes(f.read(), 'ascii')
|
||||
r = bytes(f.readall(), 'ascii')
|
||||
# check that we can write and read it correctly
|
||||
print(r == test_bytes)
|
||||
f.close()
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_UTIL_CRYPTOHASH_H
|
||||
#define MICROPY_INCLUDED_CC3200_UTIL_CRYPTOHASH_H
|
||||
|
||||
#ifndef CRYPTOHASH_H_
|
||||
#define CRYPTOHASH_H_
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
@ -34,4 +35,4 @@ extern void CRYPTOHASH_SHAMD5Start (uint32_t algo, uint32_t blocklen);
|
||||
extern void CRYPTOHASH_SHAMD5Update (uint8_t *data, uint32_t datalen);
|
||||
extern void CRYPTOHASH_SHAMD5Read (uint8_t *hash);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_UTIL_CRYPTOHASH_H
|
||||
#endif /* CRYPTOHASH_H_ */
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_UTIL_FIFO_H
|
||||
#define MICROPY_INCLUDED_CC3200_UTIL_FIFO_H
|
||||
|
||||
#ifndef FIFO_H_
|
||||
#define FIFO_H_
|
||||
|
||||
typedef struct {
|
||||
void *pvElements;
|
||||
@ -46,4 +47,4 @@ extern bool FIFO_IsEmpty (FIFO_t *fifo);
|
||||
extern bool FIFO_IsFull (FIFO_t *fifo);
|
||||
extern void FIFO_Flush (FIFO_t *fifo);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_UTIL_FIFO_H
|
||||
#endif /* FIFO_H_ */
|
||||
|
||||
@ -24,8 +24,6 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_UTIL_GCCOLLECT_H
|
||||
#define MICROPY_INCLUDED_CC3200_UTIL_GCCOLLECT_H
|
||||
|
||||
// variables defining memory layout
|
||||
extern uint32_t _etext;
|
||||
@ -41,5 +39,3 @@ extern uint32_t _stack;
|
||||
extern uint32_t _estack;
|
||||
|
||||
void gc_collect(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_UTIL_GCCOLLECT_H
|
||||
|
||||
@ -24,10 +24,11 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_UTIL_GCHELPER_H
|
||||
#define MICROPY_INCLUDED_CC3200_UTIL_GCHELPER_H
|
||||
|
||||
#ifndef GC_HELPER_H_
|
||||
#define GC_HELPER_H_
|
||||
|
||||
extern mp_uint_t gc_helper_get_sp(void);
|
||||
extern mp_uint_t gc_helper_get_regs_and_sp(mp_uint_t *regs);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_UTIL_GCHELPER_H
|
||||
#endif /* GC_HELPER_H_ */
|
||||
|
||||
@ -23,12 +23,13 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_UTIL_RANDOM_H
|
||||
#define MICROPY_INCLUDED_CC3200_UTIL_RANDOM_H
|
||||
|
||||
#ifndef __RANDOM_H
|
||||
#define __RANDOM_H
|
||||
|
||||
void rng_init0 (void);
|
||||
uint32_t rng_get (void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_0(machine_rng_get_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(machine_rng_get_obj);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_UTIL_RANDOM_H
|
||||
#endif // __RANDOM_H
|
||||
|
||||
@ -23,10 +23,11 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_UTIL_SLEEPRESTORE_H
|
||||
#define MICROPY_INCLUDED_CC3200_UTIL_SLEEPRESTORE_H
|
||||
|
||||
#ifndef SLEEPRESTORE_H_
|
||||
#define SLEEPRESTORE_H_
|
||||
|
||||
extern void sleep_store(void);
|
||||
extern void sleep_restore(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_UTIL_SLEEPRESTORE_H
|
||||
#endif /* SLEEPRESTORE_H_ */
|
||||
|
||||
@ -23,8 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_UTIL_SOCKETFIFO_H
|
||||
#define MICROPY_INCLUDED_CC3200_UTIL_SOCKETFIFO_H
|
||||
|
||||
#ifndef SOCKETFIFO_H_
|
||||
#define SOCKETFIFO_H_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
** Imports
|
||||
@ -59,4 +60,4 @@ extern bool SOCKETFIFO_IsFull (void);
|
||||
extern void SOCKETFIFO_Flush (void);
|
||||
extern unsigned int SOCKETFIFO_Count (void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_UTIL_SOCKETFIFO_H
|
||||
#endif /* SOCKETFIFO_H_ */
|
||||
|
||||
36
cc3200/util/std.h
Normal file
36
cc3200/util/std.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// 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;
|
||||
|
||||
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);
|
||||
@ -23,9 +23,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_VERSION_H
|
||||
#define MICROPY_INCLUDED_CC3200_VERSION_H
|
||||
|
||||
#ifndef VERSION_H_
|
||||
#define VERSION_H_
|
||||
|
||||
#define WIPY_SW_VERSION_NUMBER "1.2.0"
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_VERSION_H
|
||||
#endif /* VERSION_H_ */
|
||||
|
||||
@ -2,14 +2,10 @@
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
PYTHON = python3
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = build/$(MICROPY_PORT)
|
||||
CPYDIFFDIR = ../tools
|
||||
CPYDIFF = gen-cpydiff.py
|
||||
GENRSTDIR = genrst
|
||||
# Run "make FORCE= ..." to avoid rebuilding from scratch (and risk
|
||||
# producing incorrect docs).
|
||||
FORCE = -E
|
||||
@ -52,18 +48,11 @@ help:
|
||||
@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)"
|
||||
@echo " cpydiff to generate the MicroPython differences from CPython"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
rm -f $(GENRSTDIR)/*
|
||||
|
||||
cpydiff:
|
||||
@echo "Generating MicroPython Differences."
|
||||
rm -f $(GENRSTDIR)/*
|
||||
cd $(CPYDIFFDIR) && $(PYTHON) $(CPYDIFF)
|
||||
|
||||
html: cpydiff
|
||||
html:
|
||||
$(SPHINXBUILD) $(FORCE) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
@ -117,20 +106,20 @@ epub:
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex: cpydiff
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf: cpydiff
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) $(FORCE) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja: cpydiff
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
|
||||
31
docs/conf.py
31
docs/conf.py
@ -90,15 +90,16 @@ source_suffix = '.rst'
|
||||
|
||||
# General information about the project.
|
||||
project = 'MicroPython'
|
||||
copyright = '2014-2017, Damien P. George, Paul Sokolovsky, and contributors'
|
||||
copyright = '2014-2016, Damien P. George and contributors'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags"
|
||||
# breakdown, so use the same version identifier for both to avoid confusion.
|
||||
version = release = '1.9.1'
|
||||
# The short X.Y version.
|
||||
version = '1.8'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.8.4'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@ -112,11 +113,11 @@ version = release = '1.9.1'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['build', '.venv']
|
||||
exclude_patterns = ['build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
default_role = 'any'
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
@ -138,12 +139,6 @@ pygments_style = 'sphinx'
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
# Global include files. Sphinx docs suggest using rst_epilog in preference
|
||||
# of rst_prolog, so we follow. Absolute paths below mean "from the base
|
||||
# of the doctree".
|
||||
rst_epilog = """
|
||||
.. include:: /templates/replace.inc
|
||||
"""
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@ -183,7 +178,7 @@ else:
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
html_favicon = 'favicon.ico'
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
@ -251,8 +246,6 @@ latex_elements = {
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
# Include 3 levels of headers in PDF ToC
|
||||
'preamble': '\setcounter{tocdepth}{2}',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
@ -260,7 +253,7 @@ latex_elements = {
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'MicroPython.tex', 'MicroPython Documentation',
|
||||
'Damien P. George, Paul Sokolovsky, and contributors', 'manual'),
|
||||
'Damien P. George and contributors', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
@ -290,7 +283,7 @@ latex_documents = [
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'micropython', 'MicroPython Documentation',
|
||||
['Damien P. George, Paul Sokolovsky, and contributors'], 1),
|
||||
['Damien P. George and contributors'], 1),
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@ -304,7 +297,7 @@ man_pages = [
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'MicroPython', 'MicroPython Documentation',
|
||||
'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.',
|
||||
'Damien P. George and contributors', 'MicroPython', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
@ -322,7 +315,7 @@ texinfo_documents = [
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'python': ('http://docs.python.org/3', None)}
|
||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
|
||||
# Append the other ports' specific folders/files to the exclude pattern
|
||||
exclude_patterns.extend([port + '*' for port in ports if port != micropy_port])
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
.. _cpython_diffs:
|
||||
|
||||
MicroPython differences from CPython
|
||||
====================================
|
||||
|
||||
The operations listed in this section produce conflicting results in MicroPython when compared to standard Python.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
@ -58,17 +58,6 @@ For your convenience, some of technical specifications are provided below:
|
||||
and always-available BootROM bootloader, ESP8266 is not brickable.
|
||||
|
||||
|
||||
Scarcity of runtime resources
|
||||
-----------------------------
|
||||
|
||||
ESP8266 has very modest resources (first of all, RAM memory). So, please
|
||||
avoid allocating too big container objects (lists, dictionaries) and
|
||||
buffers. There is also no full-fledged OS to keep track of resources
|
||||
and automatically clean them up, so that's the task of a user/user
|
||||
application: please be sure to close open files, sockets, etc. as soon
|
||||
as possible after use.
|
||||
|
||||
|
||||
Boot process
|
||||
------------
|
||||
|
||||
@ -82,16 +71,13 @@ and developers, who can diagnose themselves any issues arising from
|
||||
modifying the standard process).
|
||||
|
||||
Once the filesystem is mounted, ``boot.py`` is executed from it. The standard
|
||||
version of this file is created during first-time module set up and has
|
||||
commands to start a WebREPL daemon (disabled by default, configurable
|
||||
with ``webrepl_setup`` module), etc. This
|
||||
file is customizable by end users (for example, you may want to set some
|
||||
parameters or add other services which should be run on
|
||||
version of this file is created during first-time module set up and by
|
||||
default starts up a WebREPL daemon to handle incoming connections. This
|
||||
file is customizable by end users (for example, you may want to disable
|
||||
WebREPL for extra security, or add other services which should be run on
|
||||
a module start-up). But keep in mind that incorrect modifications to boot.py
|
||||
may still lead to boot loops or lock ups, requiring to reflash a module
|
||||
from scratch. (In particular, it's recommended that you use either
|
||||
``webrepl_setup`` module or manual editing to configure WebREPL, but not
|
||||
both).
|
||||
from scratch.
|
||||
|
||||
As a final step of boot procedure, ``main.py`` is executed from filesystem,
|
||||
if exists. This file is a hook to start up a user application each time
|
||||
@ -107,41 +93,10 @@ This will allow to keep the structure of your application clear, as well as
|
||||
allow to install multiple applications on a board, and switch among them.
|
||||
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
Real-time clock
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
RTC in ESP8266 has very bad accuracy, drift may be seconds per minute. As
|
||||
a workaround, to measure short enough intervals you can use
|
||||
``utime.time()``, etc. functions, and for wall clock time, synchronize from
|
||||
the net using included ``ntptime.py`` module.
|
||||
---------------
|
||||
|
||||
Due to limitations of the ESP8266 chip the internal real-time clock (RTC)
|
||||
will overflow every 7:45h. If a long-term working RTC time is required then
|
||||
``time()`` or ``localtime()`` must be called at least once within 7 hours.
|
||||
MicroPython will then handle the overflow.
|
||||
|
||||
Sockets and WiFi buffers overflow
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Socket instances remain active until they are explicitly closed. This has two
|
||||
consequences. Firstly they occupy RAM, so an application which opens sockets
|
||||
without closing them may eventually run out of memory. Secondly not properly
|
||||
closed socket can cause the low-level part of the vendor WiFi stack to emit
|
||||
``Lmac`` errors. This occurs if data comes in for a socket and is not
|
||||
processed in a timely manner. This can overflow the WiFi stack input queue
|
||||
and lead to a deadlock. The only recovery is by a hard reset.
|
||||
|
||||
The above may also happen after an application terminates and quits to the REPL
|
||||
for any reason including an exception. Subsequent arrival of data provokes the
|
||||
failure with the above error message repeatedly issued. So, sockets should be
|
||||
closed in any case, regardless whether an application terminates successfully
|
||||
or by an exeption, for example using try/finally::
|
||||
|
||||
sock = socket(...)
|
||||
try:
|
||||
# Use sock
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
@ -83,12 +83,12 @@ Use the :mod:`time <utime>` module::
|
||||
time.sleep_ms(500) # sleep for 500 milliseconds
|
||||
time.sleep_us(10) # sleep for 10 microseconds
|
||||
start = time.ticks_ms() # get millisecond counter
|
||||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
||||
delta = time.ticks_diff(start, time.ticks_ms()) # compute time difference
|
||||
|
||||
Timers
|
||||
------
|
||||
|
||||
Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class
|
||||
Virtual (RTOS-based) timers are supported. Use the ``machine.Timer`` class
|
||||
with timer ID of -1::
|
||||
|
||||
from machine import Timer
|
||||
@ -102,14 +102,14 @@ The period is in milliseconds.
|
||||
Pins and GPIO
|
||||
-------------
|
||||
|
||||
Use the :ref:`machine.Pin <machine.Pin>` class::
|
||||
Use the ``machine.Pin`` class::
|
||||
|
||||
from machine import Pin
|
||||
|
||||
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
|
||||
p0.on() # set pin to "on" (high) level
|
||||
p0.off() # set pin to "off" (low) level
|
||||
p0.value(1) # set pin to on/high
|
||||
p0.high() # set pin to high
|
||||
p0.low() # set pin to low
|
||||
p0.value(1) # set pin to high
|
||||
|
||||
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
|
||||
print(p2.value()) # get value, 0 or 1
|
||||
@ -155,7 +155,7 @@ ADC (analog to digital conversion)
|
||||
ADC is available on a dedicated pin.
|
||||
Note that input voltages on the ADC pin must be between 0v and 1.0v.
|
||||
|
||||
Use the :ref:`machine.ADC <machine.ADC>` class::
|
||||
Use the ``machine.ADC`` class::
|
||||
|
||||
from machine import ADC
|
||||
|
||||
@ -166,8 +166,7 @@ Software SPI bus
|
||||
----------------
|
||||
|
||||
There are two SPI drivers. One is implemented in software (bit-banging)
|
||||
and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>`
|
||||
class::
|
||||
and works on all pins::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
@ -209,8 +208,7 @@ constructor and init (as those are fixed)::
|
||||
I2C bus
|
||||
-------
|
||||
|
||||
The I2C driver is implemented in software and works on all pins,
|
||||
and is accessed via the :ref:`machine.I2C <machine.I2C>` class::
|
||||
The I2C driver is implemented in software and works on all pins::
|
||||
|
||||
from machine import Pin, I2C
|
||||
|
||||
@ -338,27 +336,29 @@ WebREPL (web browser interactive prompt)
|
||||
WebREPL (REPL over WebSockets, accessible via a web browser) is an
|
||||
experimental feature available in ESP8266 port. Download web client
|
||||
from https://github.com/micropython/webrepl (hosted version available
|
||||
at http://micropython.org/webrepl), and configure it by executing::
|
||||
|
||||
import webrepl_setup
|
||||
|
||||
and following on-screen instructions. After reboot, it will be available
|
||||
for connection. If you disabled automatic start-up on boot, you may
|
||||
run configured daemon on demand using::
|
||||
at http://micropython.org/webrepl), and start the daemon on a device
|
||||
using::
|
||||
|
||||
import webrepl
|
||||
webrepl.start()
|
||||
|
||||
(Release versions have it started on boot by default.)
|
||||
|
||||
On a first connection, you will be prompted to set password for future
|
||||
sessions to use.
|
||||
|
||||
The supported way to use WebREPL is by connecting to ESP8266 access point,
|
||||
but the daemon is also started on STA interface if it is active, so if your
|
||||
router is set up and works correctly, you may also use WebREPL while connected
|
||||
to your normal Internet access point (use the ESP8266 AP connection method
|
||||
if you face any issues).
|
||||
|
||||
Besides terminal/command prompt access, WebREPL also has provision for file
|
||||
transfer (both upload and download). Web client has buttons for the
|
||||
corresponding functions, or you can use command-line client ``webrepl_cli.py``
|
||||
from the repository above.
|
||||
WebREPL is an experimental feature and a work in progress, and has known
|
||||
issues.
|
||||
|
||||
See the MicroPython forum for other community-supported alternatives
|
||||
to transfer files to ESP8266.
|
||||
There's also provision to transfer (both upload and download)
|
||||
files over WebREPL connection, but it has even more experimental status
|
||||
than the WebREPL terminal mode. It is still a practical way to
|
||||
get script files onto ESP8266, so give it a try using ``webrepl_cli.py``
|
||||
from the repository above. See the MicroPython forum for other
|
||||
community-supported alternatives to transfer files to ESP8266.
|
||||
|
||||
@ -64,6 +64,7 @@ device starts up.
|
||||
Accessing the filesystem via WebREPL
|
||||
------------------------------------
|
||||
|
||||
You can access the filesystem over WebREPL using the web client in a browser
|
||||
or via the command-line tool. Please refer to Quick Reference and Tutorial
|
||||
sections for more information about WebREPL.
|
||||
You can access the filesystem over WebREPL using the provided command-line
|
||||
tool. This tool is found at `<https://github.com/micropython/webrepl>`__
|
||||
and is called webrepl_cli.py. Please refer to that program for information
|
||||
on how to use it.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user