Compare commits

..

324 Commits
v1.3 ... v1.3.4

Author SHA1 Message Date
Damien George
481d714bd5 stmhal: Overhaul UART class to use read/write, and improve it.
UART object now uses a stream-like interface: read, readall, readline,
readinto, readchar, write, writechar.

Timeouts are configured when the UART object is initialised, using
timeout and timeout_char keyword args.

The object includes optional read buffering, using interrupts.  You can set
the buffer size dynamically using read_buf_len keyword arg.  A size of 0
disables buffering.
2014-10-21 22:15:20 +01:00
Damien George
20f59e182e py: Make mp_const_empty_bytes globally available. 2014-10-21 21:02:56 +01:00
Damien George
b1e217222e Merge pull request #922 from swegener/for-upstream
stmhal: Set entry point for ELF binary debugging
2014-10-21 20:58:29 +01:00
stijn
a3efe04dce Use mode/encoding kwargs in io and unicode tests
mode argument is used to assert it works
encoding argument is used to make sure CPython uses the correct encoding
as it does not automatically use utf-8
2014-10-21 22:10:38 +03:00
stijn
2fe4cf7761 Implement kwargs for builtin open() and _io.FileIO
This makes open() and _io.FileIO() more CPython compliant.
The mode kwarg is fully iplemented.
The encoding kwarg is allowed but not implemented; mainly to allow
the tests to specify encoding for CPython, see #874
2014-10-21 22:10:01 +03:00
Sven Wegener
abf0f07a5a stmhal: Set entry point for ELF binary debugging
When loading the ELF binary to the board with a debugger, the debugger
needs to know at which point to start executing the code. Currently the
entry point defaults to the start of the .text section.

Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
2014-10-21 16:48:32 +02:00
Damien George
072bd07f17 stmhal: Add retry to SD card init.
This fixed an issue with a certain SD card sometimes not initialising
first time round.  See issue #822 for related, and thanks to
@iabdalkader for the idea.
2014-10-20 00:04:27 +01:00
Damien George
0c3955b506 examples: Update conwaylife to work with new LCD API. 2014-10-19 19:02:34 +01:00
Damien George
21ca2d76a2 py: Partially fix viper multi-comparison; add test for it. 2014-10-19 19:00:51 +01:00
Damien George
9c9db3a7a1 tools, pyboard.py: Allow exec argument to be bytes or str. 2014-10-19 14:54:52 +01:00
Paul Sokolovsky
1a55b6a787 unix, stmhal: Implement file.readinto() method.
Also, usocket.readinto(). Known issue is that .readinto() should be available
only for binary files, but micropython uses single method table for both
binary and text files.
2014-10-18 22:44:07 +03:00
Damien George
c92672d7f8 unix: Make -c option parse input script as a file, as per CPython.
Addresses issue #915.
2014-10-17 23:51:39 +01:00
Damien George
b7a4b0f86f py: Improve stream_read so it doesn't need to alloc 2 bits of heap. 2014-10-17 23:34:06 +01:00
Paul Sokolovsky
297d8469b8 modure: Update to re1.5 v0.6.1, fixed and extended character class support. 2014-10-17 22:25:18 +03:00
Damien George
391db8669b py: Add more compiler optimisations for constant if/while conditions. 2014-10-17 17:57:33 +00:00
Damien George
235f9b33c8 py: Simplify compilation of elif blocks. 2014-10-17 17:30:16 +00:00
Damien George
9870fdd4b0 tests: Add test for nested while with exc and break. 2014-10-17 17:28:25 +00:00
Damien George
c30595eb1b py: Add more debug printing code in gc_dump_alloc_table. 2014-10-17 14:12:57 +00:00
Damien George
090c9236e8 py: Fix compiling of nested while/for and exception handler.
Addresses issue #912.
2014-10-17 14:08:49 +00:00
Damien George
37ada236b3 py: Take gc_pool_start out of bss section, to reclaim 1st block of heap. 2014-10-16 21:50:39 +01:00
Paul Sokolovsky
923a8a8320 stream: Handle non-blocking errors in readline() properly.
Just like they handled in other read*(). Note that behavior of readline()
in case there's no data when it's called is underspecified in Python lib
spec, implemented to behave as read() - return None.
2014-10-16 12:22:52 +03:00
Paul Sokolovsky
0c7b26c0f8 stream: Return errno value as first arg of OSError exception.
This is CPython-compatible convention established yet in acb13886fc.
2014-10-16 02:58:52 +03:00
Paul Sokolovsky
067ae1269d objclosure: Fix printing of generator closures.
The code previously assumed that only functions can be closed over.
2014-10-16 00:14:01 +03:00
Damien George
9b0b373e5e py: Fix GC realloc issue, where memory chunks were never shrunk.
Previously, a realloc to a smaller memory chunk size would not free the
unused blocks in the tail of the chunk.
2014-10-15 18:24:47 +00:00
Damien George
4859edb95b py: Fix dummy definition of BEGIN/END_ATOMIC_SECTION. 2014-10-15 17:33:24 +00:00
Paul Sokolovsky
95908b0f50 modure: Update to re1.5 v0.6, support for char sets/classes ([a-c]). 2014-10-15 04:44:07 +03:00
Damien George
d27c0bb3aa Merge pull request #905 from pfalcon/remove-zlibd
Remove zlibd, superceded by uzlib
2014-10-13 18:04:16 +01:00
Paul Sokolovsky
911c00bbc5 modzlibd: Remove, superceded by moduzlib. 2014-10-13 14:13:22 +03:00
Paul Sokolovsky
e6c5a63fab windows: Enable moduzlib instead of modzlibd. 2014-10-13 14:12:32 +03:00
Damien George
4b71c056ef moduzlib: Fix fn prototype and some code style; use it in stmhal port. 2014-10-12 23:35:38 +01:00
Damien George
29f5682621 Merge pull request #904 from pfalcon/moduzlib
Module "uzlib" - based on similarly named library
2014-10-12 23:25:24 +01:00
Paul Sokolovsky
bfb6af857a moduzlib: Import uzlib v1.1.
https://github.com/pfalcon/uzlib
2014-10-13 00:09:43 +03:00
Paul Sokolovsky
34162872b1 moduzlib: Integrate into the system. 2014-10-13 00:07:44 +03:00
Paul Sokolovsky
426bb58b23 moduzlib: New zlib-like module, based on uzlib. 2014-10-13 00:07:43 +03:00
Damien George
50062587c7 stmhal: Oops: rename mod files in Makefile. 2014-10-12 20:35:21 +01:00
Damien George
136b5cbd76 stmhal: Rename module files to keep consistency with module name. 2014-10-12 20:24:55 +01:00
Damien George
0107e90328 stmhal: Enable module weak links.
os, time, select modules are now prefixed with u, but are still
available (via weak links) as their original names.

ure and ujson now available as re and json via weak links.
2014-10-12 20:23:47 +01:00
Damien George
c14a81662c py: Add module weak link support.
With this patch a port can enable module weak link support and provide
a dict of qstr->module mapping.  This mapping is looked up only if an
import fails to find the requested module in the filesystem.

This allows to have the builtin module named, eg, usocket, and provide
a weak link of "socket" to the same module, but this weak link can be
overridden if a file by the name "socket.py" is found in the import
path.
2014-10-12 20:18:40 +01:00
Damien George
3c34d4140d py: Fix x86 viper code generation, mem8 <-> mem16 for load. 2014-10-12 16:10:25 +00:00
Damien George
91cfd414c0 py: Implement native load for viper.
Viper can now do: ptr8(buf)[0], which loads a byte from a buffer using
machine instructions.
2014-10-12 16:59:29 +01:00
Damien George
1ef2348df0 py: Implement and,or,xor native ops for viper. 2014-10-12 14:21:06 +01:00
Paul Sokolovsky
1606607bd4 modure: Make sure that re1.5 compiled in only of modure itself is enabled.
This is achieved by including re1.5 *.c files straight from modure.c .
2014-10-12 03:40:20 +03:00
Paul Sokolovsky
457c0a606c modure: Upgrade re1.5 to 0.5.1
Changes include:

regexp.h: Add double-include protection.
2014-10-12 03:12:19 +03:00
Damien George
fbf976c9aa Merge pull request #902 from pfalcon/readme-unix
README: Update "unix" section with more info/details.
2014-10-11 18:58:46 +01:00
Damien George
37671c9a97 Merge branch 'pfalcon-modure' 2014-10-11 18:55:44 +01:00
Damien George
dd5ee9ff9c stmhal: Enable ure module (tests pass on pyboard). 2014-10-11 18:55:12 +01:00
Damien George
26fa3e30ec Merge branch 'modure' of https://github.com/pfalcon/micropython into pfalcon-modure 2014-10-11 18:49:02 +01:00
Paul Sokolovsky
945df4e564 README: Update "unix" section with more info/details. 2014-10-11 20:45:32 +03:00
Damien George
1ce916aefd Merge pull request #900 from dhylands/comp-deadtime
Add support for complimentary channel output and deadtime.
2014-10-11 18:44:39 +01:00
Paul Sokolovsky
c36c75c4dc unix: Update comment MICROPY_GCREGS_SETJMP (untested -> undertested). 2014-10-11 20:33:44 +03:00
Paul Sokolovsky
6c2ab5c315 unix: Add comment about needed dependencies for MICROPY_FORCE_32BIT. 2014-10-11 20:33:37 +03:00
Paul Sokolovsky
f7bcce0552 modure: Basic tests. 2014-10-11 14:36:33 +03:00
Paul Sokolovsky
5edbadefc1 modure: Import needed files from re1.5 v0.5.
https://github.com/pfalcon/re1.5
2014-10-11 14:36:32 +03:00
Paul Sokolovsky
c71e045165 modure: Initial module, using re1.5 (which is based on re1 codebase).
https://github.com/pfalcon/re1.5
2014-10-11 14:36:32 +03:00
Dave Hylands
1c795445b3 Add support for complimentary channel output and deadtime.
This patch enables output on the complimentary channels (TIMx_CHyN).
For timers 1 and 8, deadtime can also be inserted when the channels
transition. For the pyboard, TIM8_CH1/CH1N and TIM8_CH2/CH2N can
take advantage of this.
2014-10-10 13:54:03 -07:00
Damien George
9b6617ea8b stmhal: Add pyb.stop() and pyb.standby() functions. 2014-10-09 19:02:47 +01:00
Damien George
cc5b4a2653 Merge pull request #899 from pfalcon/usocket-rename
unix: Rename "microsocket" module to "usocket".
2014-10-09 18:58:24 +01:00
Paul Sokolovsky
23b3b04072 unix: Rename "microsocket" module to "usocket".
Per new conventions, we'd like to consistently use "u*" naming conventions
for modules which don't offer complete CPython compatibility, while offer
subset or similar API.
2014-10-09 20:43:10 +03:00
Paul Sokolovsky
a2d8f98a7e examples: Rename unix socket examples to have more precise naming (http). 2014-10-09 20:35:56 +03:00
Damien George
1e49b151a7 Merge branch 'master' of github.com:micropython/micropython 2014-10-09 16:54:14 +01:00
Damien George
f0f964807e Merge branch 'dhylands-lexer-crash' 2014-10-09 16:54:03 +01:00
Damien George
9bf5f2857d py: Add further checks for failed malloc in lexer init functions. 2014-10-09 16:53:37 +01:00
Damien George
a8202762f0 Merge branch 'lexer-crash' of https://github.com/dhylands/micropython into dhylands-lexer-crash 2014-10-09 16:48:55 +01:00
Damien George
40e4c777a1 Merge pull request #897 from tomvonclef/master
Updating README.md. The Unix build requires pkg-config for FFI.
2014-10-09 16:47:06 +01:00
Damien George
7989b07637 Merge branch 'dhylands-memory-error' 2014-10-09 16:45:15 +01:00
Damien George
4091445612 py: Add #if guard around gc-specific code. 2014-10-09 16:44:43 +01:00
Dave Hylands
e20cbbec73 Make lexer fail gracefully when memory can't be allocated. 2014-10-08 23:17:35 -07:00
Tom von Clef
2090a98e80 Updating README.md to include the fact that the Unix build requires pkg-config to build the FFI module. 2014-10-08 17:26:03 -04:00
Dave Hylands
3556e45711 Allow real memory errors (from locked gc) to be reported with traceback. 2014-10-07 08:07:49 -07:00
Paul Sokolovsky
67f25dfe6f travis: Install realpath, required for teensy build. 2014-10-06 23:49:17 +03:00
Paul Sokolovsky
5d328cbeb9 windows: mingw32 gcc doesn't define endianness macros, so just assume little.
Specifically, at least Ubuntu's i586-mingw32msvc-gcc doesn't supply
__LITTLE_ENDIAN__ and friends. And as it's safe enough to assume that
Windows is only little-endian, then it's defined unconditionally,
instead of duplicating detection logic in py/mpconfig.h (or adding
windows-specific defines to it).
2014-10-06 23:18:59 +03:00
Paul Sokolovsky
5dc8f9b28a tests: Skip ffi_float.py if module ffi is not available. 2014-10-06 22:37:40 +03:00
Paul Sokolovsky
9aeec0e3a3 tests: Add missing "import sys". 2014-10-06 22:30:46 +03:00
Damien George
f53c343363 tests: Force skip of LE test on non-LE arch; improve run-tests-exp.sh. 2014-10-06 17:35:46 +00:00
Damien George
9c6f7378f7 tests: Make run-tests-exp.sh skip tests that fail due to invalid decorator.
Should address issue #856.
2014-10-06 17:06:49 +00:00
Damien George
f32498fe04 py: Extra autodetect for little endianness using __LITTLE_ENDIAN__. 2014-10-06 16:09:31 +00:00
Damien George
fec70ad369 stmhal: Remove long-obsolete pybwlan.[ch] files from old CC3k driver. 2014-10-06 15:40:25 +00:00
Damien George
9336ee320a py: Make mp_binary_set_val work on big endian machine. 2014-10-06 15:05:35 +00:00
Damien George
fcdb239815 py: Make int.to_bytes work on big endian machine.
Partly addresses issue #856.
2014-10-06 13:45:34 +00:00
Damien George
a9bcd51dc7 py: Try to autodetect machine endianness when not defined by port. 2014-10-06 13:44:59 +00:00
Damien George
5a04e2cca8 tests: Add check for micropython.native and then skip relevant tests.
If micropython.native decorator doesn't compile, then we skill all
native/viper tests.

This patch also re-enables the ujson_loads test on NT.

Addresses issue #861, and partially addresses issue #856.
2014-10-05 22:27:12 +01:00
Damien George
854c8c0153 unix: Detect and print compile error. 2014-10-05 22:25:36 +01:00
Damien George
d03c681608 stmhal: Use mp_uint_t where appropriate.
Found these by compiling stmhal with mp_uint_t of type uint32_t instead
of unsigned int.  This actually makes a difference to the code, but just
a curiosity.
2014-10-05 21:51:54 +01:00
Damien George
c4d0868df1 py: Implement proper context save/restore for eval/exec; factor code.
This has benefits all round: code factoring for parse/compile/execute,
proper context save/restore for exec, allow to sepcify globals/locals
for eval, and reduced ROM usage by >100 bytes on stmhal and unix.

Also, the call to mp_parse_compile_execute is tail call optimised for
the import code, so it doesn't increase stack memory usage.
2014-10-05 20:13:34 +01:00
Damien George
a91ac2011f py: Make compiler return a proper exception on SyntaxError. 2014-10-05 19:01:34 +01:00
Damien George
6dba992182 stmhal: Add config option to disable/enable CAN driver. 2014-10-05 18:05:26 +01:00
Damien George
ba0383a8c7 stmhal, timer: Fix timer.chanel so mode can be a keyword. 2014-10-05 17:52:45 +01:00
Damien George
55f68b3ce8 stmhal, timer: Improve accuracy of freq computation. 2014-10-05 17:52:45 +01:00
Damien George
97ef94df83 stmhal, timer: Set freq from float; get timer source freq.
Timers now have the following new features:
- can init freq using floating point; eg tim.init(freq=0.1)
- tim.source_freq() added to get freq of timer clock source
- tim.freq() added to get/set freq
- print(tim) now prints freq
2014-10-05 17:52:44 +01:00
Damien George
c3ab90da46 tests: Make printing of floats hopefully more portable. 2014-10-05 17:50:02 +01:00
Damien George
d112cbfd7c Merge pull request #891 from stinos/windows-tests
windows tests fixes
2014-10-05 17:48:37 +01:00
stijn
dc1ea1156a Exclude some tests which always fail on windows 2014-10-05 09:32:26 +02:00
stijn
a2f9c9445a Enable unicode for Windows port so unicode tests give correct uPy output 2014-10-04 09:16:20 +02:00
Damien George
24119176e7 stmhal: Allow pyb.freq() function to change SYSCLK frequency.
Eg pyb.freq(120000000) sets the CPU to 120MHz.  The frequency can be set
at any point in the code, and can be changed as many times as you like.
Note that any active timers will need to be reconfigured after a freq
change.

Valid range is 24MHz to 168MHz (but not all freqs are supported).  The
code maintains a 48MHz clock for the USB at all times and it's possible
to change the frequency at a USB REPL and keep the REPL alive (well,
most of the time it stays, sometimes it resets the USB for some reason).
Note that USB does not work with pyb.freq of 24MHz.
2014-10-04 01:54:31 +01:00
Damien George
c568a2b443 stmhal: Adjust computation of SYSCLK to retain precision. 2014-10-04 01:54:02 +01:00
Damien George
1f2558d647 Merge pull request #889 from Vogtinator/master
Implement missing ARM emitter functions for viper
2014-10-04 00:26:05 +01:00
Fabian Vogt
e5268963c6 Implement missing ARM emitter functions for viper 2014-10-04 00:57:21 +02:00
Damien George
00be7a849a py: Fix unix-cpy to compile with uint->mp_uint_t changes. 2014-10-03 20:05:44 +01:00
Damien George
39dc145478 py: Change [u]int to mp_[u]int_t in qstr.[ch], and some other places.
This should pretty much resolve issue #50.
2014-10-03 19:52:22 +01:00
Damien George
3eaa0c3833 py: Use UINT_FMT instead of %d. 2014-10-03 17:54:25 +00:00
Damien George
42f3de924b py: Convert [u]int to mp_[u]int_t where appropriate.
Addressing issue #50.
2014-10-03 17:44:14 +00:00
Damien George
877dba3e1a drivers: Add NRF24L01 driver (written in pure Python).
Comes with test script.  Copy both files to pyboard and run
"import nrf24l01test".
2014-10-02 19:36:56 +01:00
Damien George
e535a61983 tests: Add simple CAN test. 2014-10-02 17:32:02 +01:00
Damien George
3550de4ebe stmhal: Add basic CAN bus support. 2014-10-02 17:32:02 +01:00
Damien George
5fc6aa8100 stmhal: Set is_enabled=false when creating UART object; fix doc typo. 2014-10-02 17:31:37 +01:00
Damien George
0bbe4de527 stmhal: Update help text.
Remove reference to pyb.gc; add reference to pyb.millis.

There are lots of functions not listed when you run help(), but it would
be too much to list them all, so we list only some basic, useful ones.

Addresses issue #846.
2014-10-02 14:51:17 +01:00
blmorris
3b064370f8 Enable device keyword option when running pyboard.py --tests and run-tests --pyboard 2014-10-01 23:31:52 +01:00
Damien George
762d57519d unix: Do a proper clean-up on sys.exit/SystemExit.
Addresses issue #859.
2014-10-01 23:18:39 +01:00
Dave Hylands
d368611ea6 Proposed fix for USB Mass Storage. 2014-10-01 22:52:02 +01:00
Damien George
c737086e1c tools: Add network build to auto-build script. 2014-09-30 23:04:08 +00:00
Damien George
de37775a26 stmhal: Enable patch_program in cc3k driver, with key. 2014-09-30 23:43:38 +01:00
Damien George
e5cc4b2503 stmhal: Fix wiznet5k init of SPI bus. 2014-09-30 23:34:18 +01:00
Damien George
8762418d0c drivers, cc3000: Wrap exported functions in a macro for renaming. 2014-09-30 23:25:42 +01:00
Damien George
9d2bf9c405 drivers, wiznet5k: Wrap exported functions in a macro for renaming.
3rd party drivers should not export generic names like "close".
2014-09-30 22:51:47 +01:00
Damien George
3a1c4c5bc6 stmhal: Add network and usocket module.
As per issue #876, the network module is used to configure NICs
(hardware modules) and configure routing.  The usocket module is
supposed to implement the normal Python socket module and selects the
underlying NIC using routing logic.

Right now the routing logic is brain dead: first-initialised,
first-used.  And the routing table is just a list of registered NICs.

cc3k and wiznet5k work, but not at the same time due to C name clashes
(to be fixed).

Note that the usocket module has alias socket, so that one can import
socket and it works as normal.  But you can also override socket with
your own module, using usocket at the backend.
2014-09-30 22:36:47 +01:00
Damien George
bfa7b480a7 stmhal: For spi_init, add argument to select if NSS pin is enabled.
Most of the time you don't use the NSS pin of the SPI bus, and so it
shouldn't be enabled by default (this gave some bugs in the past).
2014-09-30 22:36:47 +01:00
Damien George
8b03d944e2 py: Remove IOError since it's deprecated; use OSError instead.
In CPython IOError (and EnvironmentError) is deprecated and aliased to
OSError.  All modules that used to raise IOError now raise OSError (or a
derived exception).

In Micro Python we never used IOError (except 1 place, incorrectly) and
so don't need to keep it.

See http://legacy.python.org/dev/peps/pep-3151/ for background.
2014-09-30 13:59:30 +00:00
Damien George
1c6a1dc740 py: Allow x86-64 to mov r16 to rm16 with extended src reg.
Fixes bug with x86-64 viper ptr16.
2014-09-29 22:44:18 +01:00
Damien George
dfef4249eb py: Fix viper store on x86; add tests for viper ptr16. 2014-09-29 21:41:41 +00:00
Damien George
e9dac3b4d0 py: Add casting to viper; add native mem stores to viper.
Viper can now do the following:

def store(p:ptr8, c:int):
    p[0] = c

This does a store of c to the memory pointed to by p using a machine
instructions inline in the code.
2014-09-29 22:10:41 +01:00
Damien George
44c96b2314 tests: Add tests for viper binary operations. 2014-09-29 19:42:06 +01:00
Damien George
3112cde900 py: Implement more binary ops for viper emitter.
This included a bit of restructuring of the assembler backends.  Note
that the ARM backend is missing a few functions and won't compile.
2014-09-29 19:42:06 +01:00
Damien George
6f81348fa2 py: Allow viper to use ints as direct conditionals in jumps.
Allows things like: if 1: ...
2014-09-29 19:42:06 +01:00
Damien George
a7329615eb py: Fix types, uint -> mp_uint_t. 2014-09-29 19:42:06 +01:00
Damien George
0b610de017 py: Make macro names in assemblers consistent, and tidy up a bit. 2014-09-29 19:42:06 +01:00
Damien George
d66e48662b py: Add store r8 and store r16 ops to asm_x86 and asm_x64. 2014-09-29 19:42:06 +01:00
Damien George
851f15f34c py: In asmthumb, clean up unit/int types and ite ops. 2014-09-29 19:42:06 +01:00
Damien George
860805aae7 unix: Remove unnecessary #defines from config. 2014-09-29 19:41:49 +01:00
Damien George
41249e17c3 stmhal, fatfs: Use stdlib for string fns; make all private fns static.
We save some code bytes by using builtin string functions.
2014-09-29 15:26:46 +01:00
Damien George
3a2795e200 stmhal: Add label to internal flash drive on creation. 2014-09-29 15:26:11 +01:00
Damien George
f042d7a4d7 stmhal: Fix edge case for timer PWM of 100%.
Also improve precision of calculating PWM percent in integer mode.
Also update teensy with edge case fix.
2014-09-29 14:15:01 +01:00
Damien George
853708738e Merge pull request #881 from dhylands/elapsed
Added pyb.elapsed_millis and pyb.elapsed_micros
2014-09-29 12:42:31 +01:00
Damien George
6e2051377f Merge pull request #880 from dhylands/irq-align
teensy: Enable 8-byte stack alignment for IRQ Handlers.
2014-09-29 12:22:53 +01:00
Damien George
305c4d49be Merge pull request #878 from bvernoux/master
Fix error: unknown type name 'size_t'
2014-09-29 12:22:16 +01:00
Damien George
bf683e6b32 Merge pull request #877 from dhylands/timer-overflow
Fix timer overflow code.
2014-09-29 12:18:48 +01:00
Dave Hylands
a21f56b2d5 Added pyb.elapsed_millis and pyb.elapsed_micros
tested using:
stmhal: https://github.com/dhylands/upy-examples/blob/master/elapsed.py
teensy: https://github.com/dhylands/upy-examples/blob/master/teensy/elapsed.py
2014-09-28 11:24:44 -07:00
Dave Hylands
ada691e704 teensy: Enable 8-byte stack alignment for IRQ Handlers. 2014-09-28 10:17:44 -07:00
bvernoux
f6f248b464 Fix error: unknown type name 'size_t' 2014-09-28 09:54:35 +02:00
Dave Hylands
39296b40d4 Fix timer overflow code.
Teensy doesn't need to worry about overflows since all of
its timers are only 16-bit.

For PWM, the pulse width needs to be able to vary from 0..period+1
(pulse-width == period+1 corresponds to 100% PWM)

I couldn't test the 0xffffffff cases since we can't currently get a
period that big in python. With a prescaler of 0, that corresponds
to a freq of 0.039 (i.e. cycle every 25.56 seconds), and we can't
set that using freq or period.

I also tested both stmhal and teensy with floats disabled, which
required a few other code changes to compile.
2014-09-27 19:40:37 -07:00
Damien George
f90b59e610 stmhal, modcc3k: Add ioctl to cc3k sockets so select works. 2014-09-26 13:52:41 +00:00
Damien George
133b083b89 py: Clean up nlr*.S to make it easier to read; fix clang .bss error.
It seems that newer versions of clang don't like the .bss directive, so
we don't use it for OSX.

Addressing issues #865 and #875.
2014-09-26 13:07:26 +00:00
Damien George
b766e79510 stmhal: Initial implementation of cc3k module and driver.
Pulled in and modified work done by mux/iabdalkader on cc3k driver, from
iabdalkader-cc3k-update branch.  That branch was terribly messy and had
too many conflicts to merge neatly.
2014-09-26 00:57:26 +01:00
Damien George
f996d8854f drivers, cc3k: Move cc3000 driver from stmhal to drivers directory. 2014-09-26 00:56:45 +01:00
Damien George
55a5b80793 docs: Make images and youtube video links work for LCD and AMP docs.
Images are currently served from micropython.org/static.  I don't know
if there is a better way to handle images.
2014-09-25 19:42:27 +01:00
Damien George
cde0ca21bf py: Simplify JSON str printing (while still conforming to JSON spec).
The JSON specs are relatively flexible and allow us to use one function
to print strings, be they ascii, bytes or utf-8 encoded.
2014-09-25 17:35:56 +01:00
Damien George
d19c256656 docs: Imported tutorials from previous documentation system. 2014-09-25 17:23:06 +01:00
Damien George
6162bea5b2 docs: Initial commit of Sphinx documentation framework. 2014-09-25 17:23:06 +01:00
blmorris
4f449120e1 Change allows tests/unix/ffi_float.py to pass on OSX 2014-09-25 16:31:30 +01:00
Damien George
2234c3f23d tests: Add test for exception matching of a tuple of exceptions. 2014-09-25 15:49:26 +01:00
Damien George
4bcd04bcad py: Tidy up exception matching; allow matching of tuple of exceptions.
Addresses issue #864.
2014-09-25 15:49:26 +01:00
Damien George
16ef60fba6 Updated CODECONVENTIONS to clarify use of integer types. 2014-09-25 15:49:26 +01:00
Damien George
b0261341d3 py: For malloc and vstr functions, use size_t exclusively for int type.
It seems most sensible to use size_t for measuring "number of bytes" in
malloc and vstr functions (since that's what size_t is for).  We don't
use mp_uint_t because malloc and vstr are not Micro Python specific.
2014-09-25 15:49:26 +01:00
Damien George
ac04a8a56a stmhal: Enable 8-byte stack alignment for IRQ handlers. 2014-09-25 15:47:53 +01:00
Damien George
e8ea0724da stmhal, timer: Factor code to compute PWM percent; improve 32bit case.
Also do the same for teensy timer code.
2014-09-25 15:44:10 +01:00
Damien George
3fafe730d3 Merge pull request #868 from dhylands/fix-teensy-float
Add pulse_width_percent to teensy.
2014-09-25 14:51:44 +01:00
Dave Hylands
53d5fa641f Add pulse_width_percent to teensy.
Fix stmhal and teensy print routines to report actual prescaler an period.
Fix teensy build to use soft-float
Add USE_ARDUINO_TOOLCHAIN option to teensy build
2014-09-23 23:19:36 -07:00
Damien George
52b5d76a6b py: Free non-interned strings in the parser when not needed.
mp_parse_node_free now frees the memory associated with non-interned
strings.  And the parser calls mp_parse_node_free when discarding a
non-used node (such as a doc string).

Also, the compiler now frees the parse tree explicitly just before it
exits (as opposed to relying on the caller to do this).

Addresses issue #708 as best we can.
2014-09-23 15:31:56 +00:00
Damien George
d6230f62c7 py: Make native emitter handle multi-compare and not/is not/not in ops. 2014-09-23 14:15:45 +00:00
Damien George
96e20c600f tests: Fix uctypes tests to run on 64bit arch; enable more native tests. 2014-09-23 14:15:45 +00:00
Damien George
5a5555e385 Merge pull request #869 from stinos/windows-up
windows: Enable input(), sys.maxsize(), ujson module, emergency exceptio...
2014-09-23 14:58:52 +01:00
Damien George
9f53275042 Merge pull request #871 from blmorris/osx_build_fix
Fix unix/Makefile to build on OSX
2014-09-23 14:57:14 +01:00
blmorris
fa6567a39f Clean up logical flow for setting LDFLAGS to build for Linux and OSX
Add more specific comments describing what is going on.
2014-09-23 09:42:18 -04:00
Damien George
eaaebf3291 stmhal: Initialise stack pointer correctly.
Stack is full descending and must be 8-byte aligned.  It must start off
pointing to just above the last byte of RAM.

Previously, stack started pointed to last byte of RAM (eg 0x2001ffff)
and so was not 8-byte aligned.  This caused a bug in combination with
alloca.

This patch also updates some debug printing code.

Addresses issue #872 (among many other undiscovered issues).
2014-09-23 10:59:05 +01:00
blmorris
8afb9b3863 Incorporate change in assignment logic suggested by dhylands 2014-09-22 23:00:42 -04:00
blmorris
1fae787493 Fix unix/Makefile to build on OSX
Force OSX to compile with clang even if gcc is available
Change LDFLAGS syntax to be compatible with clang
Fix questionable syntax on line 90
Remove extraneous tab character
2014-09-22 15:16:14 -04:00
stijn
8c41920a90 windows: Enable input(), sys.maxsize(), ujson module, emergency exception buf, os module 2014-09-22 11:10:27 +02:00
Damien George
2c180f7ccc extmod, ujson: Add test and comment for loads. 2014-09-21 23:43:03 +01:00
Damien George
df1e92ba3a extmod, ujson: Add \uxxxx parsing in json strings. 2014-09-21 23:43:03 +01:00
Damien George
fa2f1f72e0 extmod, ujson: Slight reduction in code size. 2014-09-21 23:43:03 +01:00
Damien George
89e4657c69 extmod: Add loads to ujson module. 2014-09-21 23:43:03 +01:00
Damien George
c95359ecc6 Merge branch 'dhylands-timer-pwm2' 2014-09-21 22:56:07 +01:00
Damien George
0e58c5810d stmhal: Add pulse_width_ratio to timer channel object.
This allows to set the pulse width (for PWM mode) as a ratio relative to
the period of the timer.  Eg, 0.5 is a 50% duty cycle.  You can set the
ratio in the channel init, or using channel.pulse_width_ratio; the
latter can also read the pulse width as a ratio.
2014-09-21 22:54:02 +01:00
Dave Hylands
becbc87fd7 Add Timer support (PWM, OC, IC) for stmhal and teensy 2014-09-19 09:26:13 -07:00
Damien George
2842945e76 stmhal: Fix bugs in documentation so it compiles. 2014-09-17 23:27:42 +00:00
Damien George
8bb44f69f2 lib: Add basic README. 2014-09-18 00:13:03 +01:00
Damien George
3d61528fe7 py: Add 'builtins' module. 2014-09-17 23:17:26 +01:00
Damien George
612045f53f py: Add native json printing using existing print framework.
Also add start of ujson module with dumps implemented.  Enabled in unix
and stmhal ports.  Test passes on both.
2014-09-17 22:56:34 +01:00
Damien George
8a9b999f1c py: Make dict use a bit less RAM when iterating; properly del values.
Heap RAM was being allocated to print dicts and do some other types of
iterating.  Now these iterations use 1 word of state on the stack.

Deleting elements from a dict was not allowing the value to be reclaimed
by the GC.  This is now fixed.
2014-09-17 15:53:03 +01:00
Damien George
1d7fb82f0a stmhal: Change 64-bit arithmetic to 32-bit for SD card block addressing.
By measuring SD card addresses in blocks and not bytes, one can get away
with using 32-bit numbers.

This patch also uses proper atomic lock/unlock around SD card
read/write, adds SD.info() function, and gives error code for failed
read/writes.
2014-09-15 23:49:57 +01:00
Felix Domke
6ff42c54bb stmhal/sdcard.c: add pyb.SD.write 2014-09-15 22:34:16 +01:00
Felix Domke
09de030651 stmhal/hal/src/stm32f4xx_hal_sd.c: fix SDHC card capacity 2014-09-15 22:34:07 +01:00
Damien George
d4a799f152 py: Make asm_arm_less_op take destination register as first arg.
This gets ARM native emitter working againg and addresses issue #858.
2014-09-15 16:39:24 +01:00
Damien George
b92cbe6129 py: Move definition of mp_sys_exit to core.
sys.exit always raises SystemExit so doesn't need a special
implementation for each port.  If C exit() is really needed, use the
standard os._exit function.

Also initialise mp_sys_path and mp_sys_argv in teensy port.
2014-09-15 15:53:09 +01:00
Damien George
83695596ed py: Fix build error when float disabled; add test for divmod. 2014-09-13 19:58:18 +01:00
Damien George
8594ce2280 py: Implement divmod, % and proper // for floating point.
Tested and working on unix and pyboard.
2014-09-13 18:43:09 +01:00
Damien George
5c6783496d Merge branch 'iabdalkader-memcpy' 2014-09-13 00:13:28 +01:00
Damien George
32781cce6d stmhal: Slightly improved memcpy; memset uses word store when aligned. 2014-09-13 00:12:41 +01:00
Damien George
5792500ccc Merge branch 'memcpy' of github.com:iabdalkader/micropython into iabdalkader-memcpy 2014-09-12 23:23:49 +01:00
Damien George
bb29546868 py: Load strings as objects when compiling viper.
Eventually, viper wants to be able to use raw pointers to strings and
arrays for efficient access.  But for now, let's just load strings as a
Python object so they can be used as normal.  This will anyway be
compatible with eventual intended viper behaviour.

Addresses issue #857.
2014-09-12 23:15:06 +01:00
Damien George
89ab3be0b1 Merge branch 'master' of github.com:micropython/micropython 2014-09-11 22:28:58 +01:00
Damien George
20beff9ae3 py and libm: Add asinf,acosf; print higher precision for float.
Also use less stack space when printing single precision float.

Addition of asinf and acosf addresses issue #851.
2014-09-11 22:24:45 +01:00
Damien George
5f0c18e583 Merge pull request #852 from techno/staccel_LIS3DSH
Add LIS3DSH accelometer support to staccel.py
2014-09-11 20:36:44 +01:00
iabdalkader
d60580eb5e Optimize memcpy more 2014-09-11 19:01:48 +02:00
Hirotaka Kawata
2b4af54992 Add LIS3DSH accelometer support to staccel.py 2014-09-11 16:40:53 +09:00
iabdalkader
81b2ddf5d1 Memcpy: copy words 2014-09-11 07:49:21 +02:00
Damien George
953074315e py: Enable struct/binary-helper to parse q and Q sized ints.
Addresses issue #848.
2014-09-10 22:10:33 +01:00
Damien George
6eae861685 py: Put define of x86 argument registers in asmx86.h. 2014-09-08 22:16:35 +00:00
Damien George
7ff996c237 py: Convert [u]int to mp_[u]int_t in emit.h and associated .c files.
Towards resolving issue #50.
2014-09-08 23:05:16 +01:00
Damien George
377b80b624 py: Print imported module's location (__file__) if available. 2014-09-08 10:45:23 +01:00
Damien George
5c00757a5c stmhal: uart ioctl uses EINVAL, and checks TXE bit for write-ability. 2014-09-07 20:57:18 +01:00
Damien George
013d53c0b4 Remove skeletal modselect from extmod and just put it in stmhal. 2014-09-07 20:42:01 +01:00
Damien George
e2a618615d stmhal: Fix modselect so non-hashable objects can be polled. 2014-09-07 20:41:09 +01:00
Damien George
c7687ad7e6 py: Rename mp_builtin_id to mp_obj_id and make it public. 2014-09-07 20:41:09 +01:00
Damien George
a2f55fe12b stmhal: Add polling ability to UART object. 2014-09-07 20:40:32 +01:00
Damien George
6c9c7bc75a stmhal: Implement generic select.select and select.poll. 2014-09-07 20:40:32 +01:00
Damien George
c8c44a4c2e py: Add ioctl method to stream protocol; add initial modselect. 2014-09-07 20:40:10 +01:00
Damien George
8105736982 py: Clean up x86-64 native assembler; allow use of extended regs.
Native x86-64 now has 3 locals in registers.
2014-09-07 01:06:19 +01:00
Damien George
25d904105c py: Adjust regs for x86 so that 1 more local can live in a reg. 2014-09-06 23:24:32 +00:00
Damien George
91fe0d4880 unix: Fix modffi to be able to return double on x86 machines. 2014-09-06 23:04:42 +00:00
Damien George
03281b3850 py: Allow x86 native functions to take arguments.
Fix some bugs with x86 stack and saving registers correctly.
2014-09-06 22:38:50 +00:00
Damien George
c90f59ec3a py: Add support for emitting native x86 machine code. 2014-09-06 23:06:36 +01:00
Damien George
33b50a0217 Merge branch 'master' of github.com:micropython/micropython 2014-09-06 18:39:39 +01:00
Damien George
c7a79284bb tests: Enable misc tests on pyboard; output 4 sig figs in rge_sm. 2014-09-06 18:38:55 +01:00
Damien George
e6ce10a3e7 py: Native emitter now supports delete name & global, and end finally. 2014-09-06 18:38:20 +01:00
Paul Sokolovsky
78fde4819c modstruct: Implement 'O', 'P', 's' types for packed structs.
This is required to deal with, well, packed C structs containing pointers.
2014-09-06 20:22:06 +03:00
Paul Sokolovsky
722e562736 py: Correctly set sys.maxsize value for 64-bit.
Type representing signed size doesn't have to be int, so use special value
which defaults to SSIZE_MAX, but as it's not defined by C standard (but rather
by POSIX), allow ports to set it.
2014-09-06 20:22:06 +03:00
Damien George
17598d49e1 unix: Don't use -Wno-error=cpp or #warning; fix strict alias warning.
For the sake of older versions of gcc (and other compilers), don't use
the #warning CPP directive, nor the -Wno-error=cpp option.

Also, fix a strict alias warning in modffi.c for older compilers, and
add a test for ffi module.

Addresses issue #847.
2014-09-06 17:46:52 +01:00
Damien George
8002d5d2b9 py: Fix definition of sys.maxsize with mpz changes. 2014-09-06 17:37:29 +01:00
Damien George
9a21d2e070 py: Make mpz able to use 16 bits per digit; and 32 on 64-bit arch.
Previously, mpz was restricted to using at most 15 bits in each digit,
where a digit was a uint16_t.

With this patch, mpz can use all 16 bits in the uint16_t (improvement
to mpn_div was required).  This gives small inprovements in speed and
RAM usage.  It also yields savings in ROM code size because all of the
digit masking operations become no-ops.

Also, mpz can now use a uint32_t as the digit type, and hence use 32
bits per digit.  This will give decent improvements in mpz speed on
64-bit machines.

Test for big integer division added.
2014-09-06 17:15:34 +01:00
Damien George
afb1cf75dd py: Convert (u)int to mp_(u)int_t in mpz, and remove unused function. 2014-09-05 20:37:06 +01:00
Damien George
e191d42188 py: Use % str formatting instead of {} in makeqstrdata.py.
Script is equivalent, but now also runs under ancient Python 2.6.
Goes part way to addressing issue #847.
2014-09-05 13:16:19 +01:00
Damien George
b534e1b9f1 py: Use variable length encoded uints in more places in bytecode.
Code-info size, block name, source name, n_state and n_exc_stack now use
variable length encoded uints.  This saves 7-9 bytes per bytecode
function for most functions.
2014-09-04 14:44:01 +01:00
Damien George
dda46460ff Code style/whitespace cleanup; remove obsolete headers.
And move the MAP_ANON redefinition from py/asmx64.c to unix/alloc.c.
2014-09-03 22:47:23 +01:00
Damien George
a669cbc690 unix: Auto-detect MICROPY_EMIT_X64 and MICROPY_GCREGS_SETJMP.
If not set, MICROPY_EMIT_X64 is set only if on x86-64 machine.

If not set, MICROPY_GCREGS_SETJMP is set when on MIPS.
2014-09-03 22:40:15 +01:00
Damien George
91fbea2c1e Merge pull request #845 from Vogtinator/master
Add allocation macros (per platform) and ARM cache flush
2014-09-03 22:31:08 +01:00
Fabian Vogt
b7235b8412 Add cache flush in py/asmarm.c and add new MP_PLAT_ALLOC_EXEC and MP_PLAT_FREE_EXEC macros
Fixes issue #840
2014-09-03 23:07:42 +02:00
Damien George
fc54250d31 Merge pull request #844 from chrisdearman/do_str
Declare do_str() function before the implementation
2014-09-03 21:53:48 +01:00
Damien George
27dd910c44 Merge branch 'stinos-msvc-extmod' 2014-09-02 11:39:12 +01:00
Damien George
e875e3882d extmod: Fix type-punned-ptr error. 2014-09-02 11:38:45 +01:00
Damien George
bc9f34860b Merge branch 'msvc-extmod' of github.com:stinos/micropython into stinos-msvc-extmod 2014-09-02 11:37:47 +01:00
stijn
759138caee msvc: Exclude modtermios, include extmod and fix compilation error 2014-09-02 09:00:20 +02:00
Chris Dearman
8c56241c82 Declare do_str() function before the implementation
This ensures that GCC does not discard the do_str implementation in
some cases eg when compiling tests with debug enabled:
  make RUN_TESTS=1 DEBUG=1
2014-09-01 19:51:12 -07:00
Damien George
bad2df3e95 stmhal, modwiznet5k: Add very minimal documentation. 2014-09-01 22:58:22 +01:00
Damien George
bcf041f1a3 stmhal: Add wiznet5k module, to control WIZnet ethernet adaptor.
Allows to create socket objects that support TCP and UDP in server and
client mode.  Interface is very close to standard Python socket class,
except bind and accept do not work the same (due to hardware not
supporting them in the usual way).

Not compiled by default.  To compile this module, use:
make MICROPY_PY_WIZNET5K=1
2014-09-01 22:52:38 +01:00
Damien George
cdd40f149a drivers, wiznet5k: Make DNS service use HAL sys tick. 2014-09-01 22:52:38 +01:00
Damien George
9091e84454 drivers, wiznet5k: Add HAL_Delay(1) to "infinite" loops. 2014-09-01 22:52:38 +01:00
Damien George
7da9145e47 drivers, wiznet5k: Properly fix ARP bug with W5200 chipset. 2014-09-01 22:52:37 +01:00
Damien George
0c0550bff0 drivers, wiznet5k: Add W5200 support. 2014-09-01 22:52:37 +01:00
Damien George
79d17e3e7d drivers, wiznet5k: Change SPI interface to read/write multiple bytes. 2014-09-01 22:52:37 +01:00
Damien George
812cf62f43 drivers, wiznet5k: Fix IP addr verification. 2014-09-01 22:52:37 +01:00
Damien George
71224cb8db drivers: Initial import of WIZnet5x000 driver. 2014-09-01 22:52:37 +01:00
Damien George
e07737d202 Added 'drivers' directory, intended to hold code for specific hardware. 2014-09-01 22:52:37 +01:00
Damien George
90fad65d2f Merge pull request #841 from dhylands/teensy-README
Update teensy README.md file
2014-08-31 00:36:54 +01:00
Dave Hylands
76dd7e180f Update teensy README.md file
Thanks to Artur Wroblewski for some suggested changes.
I also added the TIPs section at the end while I was updating.
2014-08-30 12:21:08 -07:00
Damien George
ca6d75f16d py: Small simplifications in tuple and list accessors. 2014-08-30 15:17:47 +01:00
Damien George
4abff7500f py: Change uint to mp_uint_t in runtime.h, stackctrl.h, binary.h.
Part of code cleanup, working towards resolving issue #50.
2014-08-30 14:59:21 +01:00
Damien George
4d91723587 py: Remove use of int type in obj.h.
Part of code cleanup, working towards resolving issue #50.
2014-08-30 14:28:06 +01:00
Damien George
d182b98a37 py: Change all uint to mp_uint_t in obj.h.
Part of code cleanup, working towards resolving issue #50.
2014-08-30 14:19:41 +01:00
Damien George
9c4cbe2ac0 py: Make tuple and list use mp_int_t/mp_uint_t.
Part of code cleanup, to resolve issue #50.
2014-08-30 14:04:14 +01:00
Damien George
93965e726f py: Make map, dict, set use mp_int_t/mp_uint_t exclusively.
Part of code cleanup, towards resolving issue #50.
2014-08-30 13:23:35 +01:00
Damien George
1c70cbf151 py: Save about 200 bytes of ROM by using smaller type for static table. 2014-08-30 00:38:16 +01:00
Damien George
ecc88e949c Change some parts of the core API to use mp_uint_t instead of uint/int.
Addressing issue #50, still some way to go yet.
2014-08-30 00:35:11 +01:00
Damien George
4d3fc46326 lib, libm: Add back dummy definition of tanf. 2014-08-29 23:24:00 +01:00
Damien George
8707ea3421 lib: Add lib and libm, moving current files from stmhal.
Top-level lib directory is for standard C libraries that we want to
provide our own versions of (for efficiency and stand-alone reasons).
It currently has libm in it for math functions.

Also add atanf and atan2f, which addresses issue #837.
2014-08-29 22:42:26 +01:00
Damien George
17ae2395c2 py: Use memmove instead of memcpy when appropriate.
Found this bug by running unix/ tests with DEBUG=1 enabled when
compiling.
2014-08-29 21:07:54 +01:00
Damien George
02d95d7ce9 py: Fix 2 bugs in native emitter: jump_or_pop and stack settling.
Addresses issue #838.
2014-08-29 20:05:32 +01:00
Damien George
eb4e18f057 py: Add compiler optimisation for conditions in parenthesis.
Optimises:
    if () -> if False
    if (x,...) -> if True
    if (a and b) -> if a and b
2014-08-29 20:04:01 +01:00
Damien George
15d2fe8da4 tests: Add option to run-tests to enable native emitter. 2014-08-29 19:47:10 +01:00
Damien George
110ba35980 py: Move native glue code from runtime.c to new file nativeglue.c.
This way, the native glue code is only compiled if native code is
enabled (which makes complete sense; thanks to Paul Sokolovsky for
the idea).

Should fix issue #834.
2014-08-28 23:37:02 +01:00
Damien George
1ac6faa732 Merge pull request #833 from Vogtinator/arm-native
Basic native ARM emitter
2014-08-28 23:24:43 +01:00
Damien George
516b09efc3 py, gc: Further reduce heap fragmentation with new, faster gc alloc.
The heap allocation is now exactly as it was before the "faster gc
alloc" patch, but it's still nearly as fast.  It is fixed by being
careful to always update the "last free block" pointer whenever the heap
changes (eg free or realloc).

Tested on all tests by enabling EXTENSIVE_HEAP_PROFILING in py/gc.c:
old and new allocator have exactly the same behaviour, just the new one
is much faster.
2014-08-28 23:06:38 +01:00
Damien George
b796e3d848 py: Reduce fragmentation of GC heap.
Recent speed up of GC allocation made the GC have a fragmented heap.
This patch restores "original fragmentation behaviour" whilst still
retaining relatively fast allocation.  This patch works because there is
always going to be a single block allocated now and then, which advances
the gc_last_free_atb_index pointer often enough so that the whole heap
doesn't need scanning.

Should address issue #836.
2014-08-28 10:18:40 +01:00
Fabian Vogt
16ee30c6fa Clarify copyright on asmarm files 2014-08-28 01:18:56 +02:00
Fabian Vogt
fe3d16e8c2 Basic native ARM emitter 2014-08-27 18:18:50 +02:00
Damien George
a97e091d4e Merge branch 'dhylands-int-bytes' 2014-08-27 09:21:41 +01:00
Damien George
a75b02ea9b py: Improve efficiency of MP_OBJ_IS_STR_OR_BYTES.
Saves ROM (16 on stmhal, 240 on 64-bit unix) and should be quicker since
there is 1 less branch.
2014-08-27 09:20:30 +01:00
Damien George
ad4c014d46 Merge branch 'int-bytes' of https://github.com/dhylands/micropython into dhylands-int-bytes 2014-08-27 09:13:15 +01:00
Dave Hylands
b7f7c655ed Make int(b'123') work properly. 2014-08-26 19:15:04 -07:00
Paul Sokolovsky
f3c3010ffc pip-micropython: Revert to using PIP_MICROPY_DEST environment var.
-t/--target is a pip option. Trying to use pip options for different meanings
in pip-micropython may lead to big confusion. That's why the original passed
any extra parameters using environment variables. "All options belong to pip."
2014-08-27 02:53:06 +03:00
Damien George
b427d6ae86 py: Fix line number printing for file with 1 line.
With a file with 1 line (and an error on that line), used to show the
line as number 0.  Now shows it correctly as line number 1.

But, when line numbers are disabled, it now prints line number 1 for any
line that has an error (instead of 0 as previously).  This might end up
being confusing, but requires extra RAM and/or hack logic to make it
print something special in the case of no line numbers.
2014-08-26 23:35:57 +01:00
Damien George
f05b87bd63 Merge pull request #824 from dhylands/sdcard-power
Fix sdcard_power_on to not do anything if the card is already powered on...
2014-08-26 22:58:54 +01:00
Damien George
3b72da674e stmhal, STM32F4DISC: Small changes to ST accel driver. 2014-08-26 22:41:27 +01:00
Damien George
6cf8dd4f51 Merge branch 'siorpaes-master' 2014-08-26 17:31:21 +01:00
Damien George
e00fb08f99 stmhal, staccel.py: Style cleanup. 2014-08-26 17:30:48 +01:00
David Siorpaes
f4ce26de5c Added LIS302DL ID check 2014-08-26 18:23:00 +02:00
Damien George
db63660c19 Add pip-micropython to unix make install.
Also add -t/--target option to pip-micropython to allowing installing to
the pyboard.

Thanks to turbinenreiter/Sebastian Plamauer for the patch.
2014-08-26 16:03:57 +01:00
Damien George
3bb7efc943 stmhal: Hookup USB_VCP.any().
Thanks to Dave Hylands for this patch.
2014-08-26 14:18:22 +01:00
Damien George
cd021bfe56 stmhal: Fix build issues with (old) CC3000 driver.
Addresses issue #825.
2014-08-26 14:13:53 +01:00
Damien George
779794a680 py: Add dispatch for user defined ==, >, <=, >=.
Addresses issue #827.
2014-08-26 09:31:26 +01:00
Damien George
fa1a9bc9fd tests: Add test for pyb.disable_irq and pyb.enable_irq. 2014-08-25 18:44:10 +01:00
Dave Hylands
994bb4a839 Fix sdcard_power_on to not do anything if the card is already powered on. 2014-08-25 10:16:52 -07:00
Damien George
34e43c7ee9 stmhal: Improve efficiency of SysTick IRQ and HAL_Delay.
SysTick IRQ now increases millisecond counter directly (ie without
calling HAL_IncTick).  Provide our own version of HAL_Delay that does a
wfi while waiting.  This more than halves power consumption when running
a loop containing a pyb.delay call.  It used to be like this, but new
version of HAL library regressed this feature.
2014-08-25 18:12:44 +01:00
Damien George
3475b04101 teensy: Fix multiple definition of irq functions. 2014-08-25 18:12:23 +01:00
Damien George
29c92a407c stmhal: Use MP_OBJ_NEW_SMALL_INT directly in pyb.micros/millis.
Also some whitespace cleanup.
2014-08-25 17:38:55 +01:00
Dave Hylands
2bf044442e Add support for pyb.micros() by using the systick timer.
I also removed trailing spaces from modpyb.c which affected a couple
of lines technically not part of this patch.

Tested using: https://github.com/dhylands/upy-examples/blob/master/micros_test.py

which eventually fails due to wraparound issues (I could fix the test to compensate
but didn't bother)
2014-08-25 17:38:55 +01:00
Dave Hylands
8c0add4eee Add save/restore_irq
Factored irq functions into a separate file.
2014-08-25 17:38:55 +01:00
Damien George
e5cbb70328 stmhal: Make enable_irq and disable_irq inline functions.
These functions are generally 1 machine instruction, and are used in
critical code, so makes sense to have them inline.

Also leave these functions uninverted (ie 0 means enable, 1 means
disable) and provide macro constants if you really need to distinguish
the states.  This makes for smaller code as well (combined with
inlining).

Applied to teensy port as well.
2014-08-25 13:24:33 +01:00
Dave Hylands
9480138f0c Add save/restore_irq
Factored irq functions into a separate file.
2014-08-25 12:22:11 +01:00
Damien George
7310fd469a py: Consolidate min/max functions into one, and add key= argument.
Addresses issue #811.
2014-08-24 19:14:09 +01:00
Damien George
1d8a06406a examples: Added pins.py example script to list pin config/af.
Script is due to Dave Hylands.
2014-08-24 18:34:38 +01:00
Damien George
2c4e67e32d stmhal, pin: Update documentation. 2014-08-24 18:30:22 +01:00
Dave Hylands
3d945559d4 Added python script to map AF to a pin name
Added some functions to Pin class to query mode, pull, and af
2014-08-24 18:21:08 +01:00
Damien George
c668d51b08 Merge branch 'dhylands-localtime' 2014-08-24 17:41:31 +01:00
Damien George
8ba832456e stmhal, modtime: Small changes, reduced code size by around 80 bytes.
Also added test for modtime.
2014-08-24 17:40:24 +01:00
Dave Hylands
6678595e7e Add time.mktime and enhance time.localtime (for stmhal)
Now you can use time.localtime on the timestamps presented by os.stat
2014-08-24 17:00:03 +01:00
Damien George
3c658a4e75 py: Fix bug where GC collected native/viper/asm function data.
Because (for Thumb) a function pointer has the LSB set, pointers to
dynamic functions in RAM (eg native, viper or asm functions) were not
being traced by the GC.  This patch is a comprehensive fix for this.

Addresses issue #820.
2014-08-24 16:28:17 +01:00
Damien George
25fc41dd31 unix, modtermios: Make it properly configurable; fix spelling mistake. 2014-08-24 13:19:22 +01:00
Paul Sokolovsky
4f9ebade60 modtermios: Add "termios" unix module, subset of CPython's.
Also provides setraw() function from "tty" module (which in CPython is
implemented in Python). The idea here is that 95% of "termios" module usage
is to set raw mode to allow access to normal serial devices. Then, instead
of exporting gazillion termios symbols, it's better to implement it in C,
and export minimal number of symbols (mostly baud rates and drain values).
2014-08-23 06:09:46 +03:00
Damien George
72b115cbaa extmod, zlibd: Make some simple ROM and RAM savings.
ROM down by 320 bytes on stmhal.  RAM down by 5.5k for a decompression
object.
2014-08-22 18:38:16 +01:00
Damien George
26a0d4f4f1 py: Change hash and len members of str from 16 bit to full word.
This allows to make strings longer than 64k.  It doesn't use any more
RAM with current GC because a str object still fits in a GC block.
2014-08-22 18:34:28 +01:00
Damien George
69b7dae362 py: Small cleanup in stream.c. 2014-08-22 18:30:02 +01:00
Damien George
d5e7f6e37e py: Speed up GC allocation.
This simple patch gives a very significant speed up for memory allocation
with the GC.

Eg, on PYBv1.0:
tests/basics/dict_del.py: 3.55 seconds -> 1.19 seconds
tests/misc/rge_sm.py:     15.3 seconds -> 2.48 seconds
2014-08-22 18:17:02 +01:00
Paul Sokolovsky
13ec400f28 Merge pull request #796 from turbinenreiter/makeinstall
unix: Added install/uninstall
2014-08-18 22:29:37 +03:00
Damien George
7fe2191c9b py: Code clean-up in native emitter; improve thumb native calls. 2014-08-16 22:31:57 +01:00
Damien George
86de21b810 py: Viper can call functions with native types, and raise exceptions. 2014-08-16 22:06:11 +01:00
Damien George
339bdccc58 Merge pull request #803 from dhylands/ld-opt
Put some code into the first 16K of flash
2014-08-16 16:09:39 +01:00
Dave Hylands
3688414d9d Put some code into the first 16K of flash
This basically shrinks the remaining size of flash in the portion
that goes after the internal flash drive.
2014-08-16 08:00:12 -07:00
Damien George
8f81b5cb4b py: Put SystemExit in builtin namespace.
Also fix unix port so that SystemExit with no arg exits with value 0.
2014-08-16 14:32:06 +01:00
Damien George
b63be37be1 stmhal: In safe mode, still mount SD card and present as MSD over USB.
It's still "safe" because no scripts are run.  Remove the SD card if you
want to access the internal flash filesystem.  Addresses issue #616.

Also: remove obsolete pyb.source_dir setting, and reset pyb.main and
pyb.usb_mode settings on soft-reset.
2014-08-16 14:23:22 +01:00
Damien George
b0accc8571 stmhal: Fix printing of pin name in error message. 2014-08-16 13:56:19 +01:00
Damien George
d779b9642f tests: Wait for just over 1 sec when testing RTC.
Waiting for 1000ms between seconds of RTC is sometimes too quick.
Waiting for 1001ms is enough for the RTC to pass 1 second.
2014-08-16 13:39:14 +01:00
Damien George
244476e3e6 stmhal: For non-debug compile, enable CC/LD opt to remove dead code.
Saves over 35k ROM due to elimination of unused HAL functions.  All
tests pass.

Addresses issue #702.
2014-08-16 13:37:05 +01:00
Damien George
c84aa41990 Merge branch 'danpeirce-master' 2014-08-16 11:56:16 +01:00
Dan Peirce
f0c3a7e781 teensy/README.md (corrected typo) 2014-08-16 11:54:36 +01:00
Dan Peirce
6009309c33 modified: teensy/README.md
Updated teensy/README.md to reflect change in build process (teensyduino is no
longer required for build).
2014-08-16 11:54:36 +01:00
Damien George
e6c0dff967 py: Viper can now store to global. 2014-08-15 23:47:59 +01:00
Damien George
a5190a7dac py: Fix typing of viper locals; allow default types in annotation. 2014-08-15 22:39:08 +01:00
Damien George
2ac4af6946 py: Allow viper to have type annotations.
Viper functions can now be annotated with the type of their arguments
and return value.  Eg:

@micropython.viper
def f(x:int) -> int:
    return x + 1
2014-08-15 16:45:41 +01:00
Damien George
6be0b0a8ec py: Clean up and simplify functions in scope; add STATIC in compiler.
Some small code clean-ups that result in about 80 bytes ROM saving for
stmhal.
2014-08-15 14:30:52 +01:00
Damien George
bf133f7737 stmhal: Resolve question in comment about timer clock. 2014-08-14 00:30:14 +01:00
Damien George
2c781eabbd Merge pull request #798 from stinos/msvc-alignof
msvc: Use built-in alignof
2014-08-13 13:34:41 +01:00
Damien George
9b7a8ee8f1 py: Fix mult by negative number of tuple, list, str, bytes.
Multiplication of a tuple, list, str or bytes now yields an empty
sequence (instead of crashing).  Addresses issue #799

Also added ability to mult bytes on LHS by integer.
2014-08-13 13:22:24 +01:00
stijn
8cce8b7c4c msvc: Use built-in alignof
This also fixes a 'unnamed type definition in parentheses' warning on the
alignof implementation define in binary.c
2014-08-13 10:19:56 +02:00
Sebastian Plamauer
2eeeafcba5 added install/uninstall 2014-08-11 19:47:00 +02:00
391 changed files with 31488 additions and 8137 deletions

View File

@@ -8,6 +8,8 @@ before_script:
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
- sudo apt-get update -qq
- sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-arm-none-eabi qemu-system mingw32
# For teensy build
- sudo apt-get install realpath
script:
- make -C unix CC=gcc-4.7
@@ -20,6 +22,7 @@ script:
- make -C windows CROSS_COMPILE=i586-mingw32msvc-
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests)
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests --emit native)
after_failure:
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)

View File

@@ -40,6 +40,17 @@ Header files:
Type names and declarations:
- When defining a type, put '_t' after it.
Integer types: Micro Python runs on 32 and 64 bit machines (and one day
maybe 16 bit), so it's important to use the correctly-sized (and signed)
integer types. The general guidelines are:
- For most cases use mp_int_t for signed and mp_uint_t for unsigned
integer values. These are guaranteed to be machine-word sized and
therefore big enough to hold the value from a Micro Python small-int
object.
- Use size_t for things that count bytes / sizes of objects.
- You can use int/uint, but remember that they may be 16-bits wide.
- If in doubt, use mp_int_t/mp_uint_t.
Examples
--------

View File

@@ -49,23 +49,28 @@ The Unix version
The "unix" port requires a standard Unix environment with gcc and GNU make.
x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well
as ARMv7. Porting to other architectures require writing some assembly code
for the exception handling.
as ARM and MIPS. Making full-featured port to another architecture requires
writing some assembly code for the exception handling and garbage collection.
Alternatively, fallback implementation based on setjmp/longjmp can be used.
To build:
$ cd unix
$ make
Then to test it:
Then to give it a try:
$ ./micropython
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
Run complete testsuite:
$ make test
Debian/Ubuntu/Mint derivative Linux distros will require build-essentials and
libreadline-dev packages installed. To build FFI (Foreign Function Interface)
module, libffi-dev package is required. If you have problems with some
dependencies, they can be disabled in unix/mpconfigport.mk .
module, libffi-dev and pkg-config packages are required. If you have problems
with some dependencies, they can be disabled in unix/mpconfigport.mk .
The STM version
---------------

View File

@@ -35,10 +35,10 @@ void do_str(const char *src) {
qstr source_name = mp_lexer_source_name(lex);
mp_lexer_free(lex);
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
mp_parse_node_free(pn);
if (module_fun == mp_const_none) {
if (mp_obj_is_exception_instance(module_fun)) {
// compile error
mp_obj_print_exception(module_fun);
return;
}
@@ -70,10 +70,10 @@ mp_import_stat_t mp_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args) {
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_open_obj, 1, 2, mp_builtin_open);
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
void nlr_jump_fail(void *val) {
}

View File

@@ -17,6 +17,7 @@
#define MICROPY_PY_BUILTINS_SET (0)
#define MICROPY_PY_BUILTINS_SLICE (0)
#define MICROPY_PY_BUILTINS_PROPERTY (0)
#define MICROPY_PY___FILE__ (0)
#define MICROPY_PY_GC (0)
#define MICROPY_PY_ARRAY (0)
#define MICROPY_PY_COLLECTIONS (0)
@@ -35,6 +36,8 @@
#define BYTES_PER_WORD (4)
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
#define UINT_FMT "%lu"
#define INT_FMT "%ld"
@@ -44,7 +47,7 @@ typedef void *machine_ptr_t; // must be of pointer size
typedef const void *machine_const_ptr_t; // must be of pointer size
// extra built in names to add to the global namespace
extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
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 },

177
docs/Makefile Normal file
View File

@@ -0,0 +1,177 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MicroPython.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MicroPython.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/MicroPython"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MicroPython"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
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:
$(SPHINXBUILD) -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:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

269
docs/conf.py Normal file
View File

@@ -0,0 +1,269 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Micro Python documentation build configuration file, created by
# sphinx-quickstart on Sun Sep 21 11:42:03 2014.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
]
# Add any paths that contain templates here, relative to this directory.
#templates_path = ['templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'Micro Python'
copyright = '2014, Damien P. George'
# 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.
#
# The short X.Y version.
version = '1.3'
# The full version, including alpha/beta/rc tags.
release = '1.3.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# 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 = 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,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'MicroPythondoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'MicroPython.tex', 'Micro Python Documentation',
'Damien P. George', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'micropython', 'Micro Python Documentation',
['Damien P. George'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'MicroPython', 'Micro Python Documentation',
'Damien P. George', 'MicroPython', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}

59
docs/general.rst Normal file
View File

@@ -0,0 +1,59 @@
General information about the pyboard
=====================================
Local filesystem and SD card
----------------------------
There is a small internal filesystem (a drive) on the pyboard, called ``/flash``,
which is stored within the microcontroller's flash memory. If a micro SD card
is inserted into the slot, it is available as ``/sd``.
When the pyboard boots up, it needs to choose a filesystem to boot from. If
there is no SD card, then it uses the internal filesystem ``/flash`` as the boot
filesystem, otherwise, it uses the SD card ``/sd``.
(Note that on older versions of the board, ``/flash`` is called ``0:/`` and ``/sd``
is called ``1:/``).
The boot filesystem is used for 2 things: it is the filesystem from which
the ``boot.py`` and ``main.py`` files are searched for, and it is the filesystem
which is made available on your PC over the USB cable.
The filesystem will be available as a USB flash drive on your PC. You can
save files to the drive, and edit ``boot.py`` and ``main.py``.
*Remember to eject (on Linux, unmount) the USB drive before you reset your
pyboard.*
Boot modes
----------
If you power up normally, or press the reset button, the pyboard will boot
into standard mode: the ``boot.py`` file will be executed first, then the
USB will be configured, then ``main.py`` will run.
You can override this boot sequence by holding down the user switch as
the board is booting up. Hold down user switch and press reset, and then
as you continue to hold the user switch, the LEDs will count in binary.
When the LEDs have reached the mode you want, let go of the user switch,
the LEDs for the selected mode will flash quickly, and the board will boot.
The modes are:
1. Green LED only, *standard boot*: run ``boot.py`` then ``main.py``.
2. Orange LED only, *safe boot*: don't run any scripts on boot-up.
3. Green and orange LED together, *filesystem reset*: resets the flash
filesystem to its factory state, then boots in safe mode.
If your filesystem becomes corrupt, boot into mode 3 to fix it.
Errors: flashing LEDs
---------------------
There are currently 2 kinds of errors that you might see:
1. If the red and green LEDs flash alternatively, then a Python script
(eg ``main.py``) has an error. Use the REPL to debug it.
2. If all 4 LEDs cycle on and off slowly, then there was a hard fault.
This cannot be recovered from and you need to do a hard reset.

43
docs/index.rst Normal file
View File

@@ -0,0 +1,43 @@
.. Micro Python documentation master file
Micro Python documentation and references
=========================================
Here you can find documentation for Micro Python and the pyboard.
Software
--------
.. toctree::
:maxdepth: 2
general.rst
tutorial/index.rst
..
.. - Reference for the [pyb module](module/pyb/ "pyb module").
.. - Reference for [all modules](module/ "all modules").
.. - [Guide for setting up the pyboard on Windows](/static/doc/Micro-Python-Windows-setup.pdf), including DFU programming (PDF).
The pyboard hardware
--------------------
.. - PYBv1.0 [schematics and layout](/static/doc/PYBv10b.pdf "PYBv1.0") (2.4MiB PDF).
.. - PYBv1.0 [metric dimensions](/static/doc/PYBv10b-metric-dimensions.pdf "metric dimensions") (360KiB PDF).
.. - PYBv1.0 [imperial dimensions](/static/doc/PYBv10b-imperial-dimensions.pdf "imperial dimensions") (360KiB PDF).
Datasheets for the components on the pyboard
--------------------------------------------
.. - The microcontroller: [STM32F405RGT6](http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252144) (external link).
.. - The accelerometer: [Freescale MMA7660](/static/doc/MMA7660FC.pdf) (800kiB PDF).
.. - The LDO voltage regulator: [Microchip MCP1802](/static/doc/MCP1802-22053C.pdf) (400kiB PDF).
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

242
docs/make.bat Normal file
View File

@@ -0,0 +1,242 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\MicroPython.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\MicroPython.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end

92
docs/tutorial/accel.rst Normal file
View File

@@ -0,0 +1,92 @@
The accelerometer
=================
Here you will learn how to read the accelerometer and signal using LEDs states like tilt left and tilt right.
Using the accelerometer
-----------------------
The pyboard has an accelerometer (a tiny mass on a tiny spring) that can be used
to detect the angle of the board and motion. There is a different sensor for
each of the x, y, z directions. To get the value of the accelerometer, create a
pyb.Accel() object and then call the x() method. ::
>>> accel = pyb.Accel()
>>> accel.x()
7
This returns a signed integer with a value between around -30 and 30. Note that
the measurement is very noisy, this means that even if you keep the board
perfectly still there will be some variation in the number that you measure.
Because of this, you shouldn't use the exact value of the x() method but see if
it is in a certain range.
We will start by using the accelerometer to turn on a light if it is not flat. ::
accel = pyb.Accel()
light = pyb.LED(3)
SENSITIVITY = 3
while True:
x = accel.x()
if abs(x) > SENSITIVITY:
light.on()
else:
light.off()
pyb.delay(100)
We create Accel and LED objects, then get the value of the x direction of the
accelerometer. If the magnitude of x is bigger than a certain value ``SENSITIVITY``,
then the LED turns on, otherwise it turns off. The loop has a small ``pyb.delay()``
otherwise the LED flashes annoyingly when the value of x is close to
``SENSITIVITY``. Try running this on the pyboard and tilt the board left and right
to make the LED turn on and off.
**Exercise: Change the above script so that the blue LED gets brighter the more
you tilt the pyboard. HINT: You will need to rescale the values, intensity goes
from 0-255.**
Making a spirit level
---------------------
The example above is only sensitive to the angle in the x direction but if we
use the ``y()`` value and more LEDs we can turn the pyboard into a spirit level. ::
xlights = (pyb.LED(2), pyb.LED(3))
ylights = (pyb.LED(1), pyb.LED(4))
accel = pyb.Accel()
SENSITIVITY = 3
while True:
x = accel.x()
if x > SENSITIVITY:
xlights[0].on()
xlights[1].off()
elif x < -SENSITIVITY:
xlights[1].on()
xlights[0].off()
else:
xlights[0].off()
xlights[1].off()
y = accel.y()
if y > SENSITIVITY:
ylights[0].on()
ylights[1].off()
elif y < -SENSITIVITY:
ylights[1].on()
ylights[0].off()
else:
ylights[0].off()
ylights[1].off()
pyb.delay(100)
We start by creating a tuple of LED objects for the x and y directions. Tuples
are immutable objects in python which means they can't be modified once they are
created. We then proceed as before but turn on a different LED for positive and
negative x values. We then do the same for the y direction. This isn't
particularly sophisticated but it does the job. Run this on your pyboard and you
should see different LEDs turning on depending on how you tilt the board.

View File

@@ -0,0 +1,65 @@
The AMP audio skin
==================
Soldering and using the AMP audio skin.
.. image:: http://micropython.org/static/doc/skin-amp-1.jpg
:alt: AMP skin
:width: 250px
.. image:: http://micropython.org/static/doc/skin-amp-3.jpg
:alt: AMP skin
:width: 250px
The following video shows how to solder the headers, microphone and speaker onto the AMP skin.
.. raw:: html
<iframe style="margin-left:3em;" width="560" height="315" src="http://www.youtube.com/embed/fjB1DuZRveo?rel=0" frameborder="0" allowfullscreen></iframe>
Example code
------------
The AMP skin has a speaker which is connected to ``DAC(1)`` via a small
power amplifier. The volume of the amplifier is controlled by a digital
potentiometer, which is an I2C device with address 46 on the ``IC2(1)`` bus.
To set the volume, define the following function::
def volume(val):
pyb.I2C(1, pyb.I2C.MASTER).mem_write(val, 46, 0)
Then you can do::
>>> volume(0) # minimum volume
>>> volume(127) # maximum volume
To play a sound, use the ``write_timed`` method of the ``DAC`` object.
For example::
import math
from pyb import DAC
# create a buffer containing a sine-wave
buf = bytearray(100)
for i in range(len(buf)):
buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf)))
# output the sine-wave at 400Hz
dac = DAC(1)
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)
You can also play WAV files using the Python ``wave`` module. You can get
the wave module [here](/static/doc/examples/wave.py) and you will also need
the chunk module available [here](/static/doc/examples/chunk.py). Put these
on your pyboard (either on the flash or the SD card in the top-level
directory). You will need an 8-bit WAV file to play, such as
[this one](/static/doc/examples/test.wav). Then you can do::
>>> import wave
>>> from pyb import DAC
>>> dac = DAC(1)
>>> f = wave.open('test.wav')
>>> dac.write_timed(f.readframes(f.getnframes()), f.getframerate())
This should play the WAV file.

123
docs/tutorial/assembler.rst Normal file
View File

@@ -0,0 +1,123 @@
Inline assembler
================
Here you will learn how to write inline assembler in Micro Python.
**Note**: this is an advanced tutorial, intended for those who already
know a bit about microcontrollers and assembly language.
Micro Python includes an inline assembler. It allows you to write
assembly routines as a Python function, and you can call them as you would
a normal Python function.
Returning a value
-----------------
Inline assembler functions are denoted by a special function decorator.
Let's start with the simplest example::
@micropython.asm_thumb
def fun():
movw(r0, 42)
You can enter this in a script or at the REPL. This function takes no
arguments and returns the number 42. ``r0`` is a register, and the value
in this register when the function returns is the value that is returned.
Micro Python always interprets the ``r0`` as an integer, and converts it to an
integer object for the caller.
If you run ``print(fun())`` you will see it print out 42.
Accessing peripherals
---------------------
For something a bit more complicated, let's turn on an LED::
@micropython.asm_thumb
def led_on():
movwt(r0, stm.GPIOA)
movw(r1, 1 << 13)
strh(r1, [r0, stm.GPIO_BSRRL])
This code uses a few new concepts:
- ``stm`` is a module which provides a set of constants for easy
access to the registers of the pyboard's microcontroller. Try
running ``import stm`` and then ``help(stm)`` at the REPL. It will
give you a list of all the available constants.
- ``stm.GPIOA`` is the address in memory of the GPIOA peripheral.
On the pyboard, the red LED is on port A, pin PA13.
- ``movwt`` moves a 32-bit number into a register. It is a convenience
function that turns into 2 thumb instructions: ``movw`` followed by ``movt``.
The ``movt`` also shifts the immediate value right by 16 bits.
- ``strh`` stores a half-word (16 bits). The instruction above stores
the lower 16-bits of ``r1`` into the memory location ``r0 + stm.GPIO_BSRRL``.
This has the effect of setting high all those pins on port A for which
the corresponding bit in ``r0`` is set. In our example above, the 13th
bit in ``r0`` is set, so PA13 is pulled high. This turns on the red LED.
Accepting arguments
-------------------
Inline assembler functions can accept up to 3 arguments. If they are
used, they must be named ``r0``, ``r1`` and ``r2`` to reflect the registers
and the calling conventions.
Here is a function that adds its arguments::
@micropython.asm_thumb
def asm_add(r0, r1):
add(r0, r0, r1)
This performs the computation ``r0 = r0 + r1``. Since the result is put
in ``r0``, that is what is returned. Try ``asm_add(1, 2)``, it should return
3.
Loops
-----
We can assign labels with ``label(my_label)``, and branch to them using
``b(my_label)``, or a conditional branch like ``bgt(my_label)``.
The following example flashes the green LED. It flashes it ``r0`` times. ::
@micropython.asm_thumb
def flash_led(r0):
# get the GPIOA address in r1
movwt(r1, stm.GPIOA)
# get the bit mask for PA14 (the pin LED #2 is on)
movw(r2, 1 << 14)
b(loop_entry)
label(loop1)
# turn LED on
strh(r2, [r1, stm.GPIO_BSRRL])
# delay for a bit
movwt(r4, 5599900)
label(delay_on)
sub(r4, r4, 1)
cmp(r4, 0)
bgt(delay_on)
# turn LED off
strh(r2, [r1, stm.GPIO_BSRRH])
# delay for a bit
movwt(r4, 5599900)
label(delay_off)
sub(r4, r4, 1)
cmp(r4, 0)
bgt(delay_off)
# loop r0 times
sub(r0, r0, 1)
label(loop_entry)
cmp(r0, 0)
bgt(loop1)

35
docs/tutorial/index.rst Normal file
View File

@@ -0,0 +1,35 @@
.. _tutorial-index:
Micro Python tutorial
=====================
This tutorial is intended to get you started with your pyboard.
All you need is a pyboard and a micro-USB cable to connect it to
your PC. If it is your first time, it is recommended to follow
the tutorial through in the order below.
.. toctree::
:maxdepth: 1
:numbered:
intro.rst
script.rst
repl.rst
leds.rst
switch.rst
accel.rst
reset.rst
usb_mouse.rst
timer.rst
assembler.rst
Tutorials requiring extra components
------------------------------------
.. toctree::
:maxdepth: 1
:numbered:
servo.rst
lcd_skin.rst
amp_skin.rst

54
docs/tutorial/intro.rst Normal file
View File

@@ -0,0 +1,54 @@
Introduction to the pyboard
===========================
To get the most out of your pyboard, there are a few basic things to
understand about how it works.
Caring for your pyboard
-----------------------
Because the pyboard does not have a housing it needs a bit of care:
- Be gentle when plugging/unplugging the USB cable. Whilst the USB connector
is soldered through the board and is relatively strong, if it breaks off
it can be very difficult to fix.
- Static electricity can shock the components on the pyboard and destroy them.
If you experience a lot of static electricity in your area (eg dry and cold
climates), take extra care not to shock the pyboard. If your pyboard came
in a black plastic box, then this box is the best way to store and carry the
pyboard as it is an anti-static box (it is made of a conductive plastic, with
conductive foam inside).
As long as you take care of the hardware, you should be okay. It's almost
impossible to break the software on the pyboard, so feel free to play around
with writing code as much as you like. If the filesystem gets corrupt, see
below on how to reset it. In the worst case you might need to reflash the
Micro Python software, but that can be done over USB.
Layout of the pyboard
---------------------
The micro USB connector is on the top right, the micro SD card slot on
the top left of the board. There are 4 LEDs between the SD slot and
USB connector. The colours are: red on the bottom, then green, orange,
and blue on the top. There are 2 switches: the right one is the reset
switch, the left is the user switch.
Plugging in and powering on
---------------------------
The pyboard can be powered via USB. Connect it to your PC via a micro USB
cable. There is only one way that the cable will fit. Once connected,
the green LED on the board should flash quickly.
Powering by an external power source
------------------------------------
The pyboard can be powered by a battery or other external power source.
**Be sure to connect the positive lead of the power supply to VIN, and
ground to GND. There is no polarity protection on the pyboard so you
must be careful when connecting anything to VIN.**
**The input voltage must be between 3.6V and 10V.**

View File

@@ -0,0 +1,81 @@
The LCD and touch-sensor skin
=============================
Soldering and using the LCD and touch-sensor skin.
.. image:: http://micropython.org/static/doc/skin-lcd-3.jpg
:alt: pyboard with LCD skin
:width: 250px
.. image:: http://micropython.org/static/doc/skin-lcd-1.jpg
:alt: pyboard with LCD skin
:width: 250px
The following video shows how to solder the headers onto the LCD skin.
At the end of the video, it shows you how to correctly connect the LCD skin to the pyboard.
.. raw:: html
<iframe style="margin-left:3em;" width="560" height="315" src="http://www.youtube.com/embed/PowCzdLYbFM?rel=0" frameborder="0" allowfullscreen></iframe>
Using the LCD
-------------
To get started using the LCD, try the following at the Micro Python prompt.
Make sure the LCD skin is attached to the pyboard as pictured at the top of this page. ::
>>> lcd = pyb.LCD('X')
>>> lcd.light(True)
>>> lcd.write('Hello uPy!\n')
You can make a simple animation using the code::
lcd = pyb.LCD('X')
lcd.light(True)
for x in range(-80, 128):
lcd.fill(0)
lcd.text('Hello uPy!', x, 10, 1)
lcd.show()
pyb.delay(25)
Using the touch sensor
----------------------
To read the touch-sensor data you need to use the I2C bus. The
MPR121 capacitive touch sensor has address 90.
To get started, try::
>>> i2c = pyb.I2C(1, pyb.I2C.MASTER)
>>> i2c.mem_write(4, 90, 0x5e)
>>> touch = i2c.mem_read(1, 90, 0)[0]
The first line above makes an I2C object, and the second line
enables the 4 touch sensors. The third line reads the touch
status and the ``touch`` variable holds the state of the 4 touch
buttons (A, B, X, Y).
There is a simple driver [here](/static/doc/examples/mpr121.py)
which allows you to set the threshold and debounce parameters, and
easily read the touch status and electrode voltage levels. Copy
this script to your pyboard (either flash or SD card, in the top
directory or ``lib/`` directory) and then try::
>>> import pyb
>>> import mpr121
>>> m = mpr121.MPR121(pyb.I2C(1, pyb.I2C.MASTER))
>>> for i in range(100):
... print(m.touch_status())
... pyb.delay(100)
...
This will continuously print out the touch status of all electrodes.
Try touching each one in turn.
Note that if you put the LCD skin in the Y-position, then you need to
initialise the I2C bus using::
>>> m = mpr121.MPR121(pyb.I2C(2, pyb.I2C.MASTER))
There is also a demo which uses the LCD and the touch sensors together,
and can be found [here](/static/doc/examples/lcddemo.py).

75
docs/tutorial/leds.rst Normal file
View File

@@ -0,0 +1,75 @@
Turning on LEDs and basic Python concepts
=========================================
The easiest thing to do on the pyboard is to turn on the LEDs attached to the board. Connect the board, and log in as described in tutorial 1. We will start by turning and LED on in the interpreter, type the following ::
>>> myled = pyb.LED(1)
>>> myled.on()
>>> myled.off()
These commands turn the LED on and off.
This is all very well but we would like this process to be automated. Open the file MAIN.PY on the pyboard in your favourite text editor. Write or paste the following lines into the file. If you are new to python, then make sure you get the indentation correct since this matters! ::
led = pyb.LED(2)
while True:
led.toggle()
pyb.delay(1000)
When you save, the red light on the pyboard should turn on for about a second. To run the script, do a soft reset (CTRL-D). The pyboard will then restart and you should see a green light continuously flashing on and off. Success, the first step on your path to building an army of evil robots! When you are bored of the annoying flashing light then press CTRL-C at your terminal to stop it running.
So what does this code do? First we need some terminology. Python is an object-oriented language, almost everything in python is a *class* and when you create an instance of a class you get an *object*. Classes have *methods* associated to them. A method (also called a member function) is used to interact with or control the object.
The first line of code creates an LED object which we have then called led. When we create the object, it takes a single parameter which must be between 1 and 4, corresponding to the 4 LEDs on the board. The pyb.LED class has three important member functions that we will use: on(), off() and toggle(). The other function that we use is pyb.delay() this simply waits for a given time in miliseconds. Once we have created the LED object, the statement while True: creates an infinite loop which toggles the led between on and off and waits for 1 second.
**Exercise: Try changing the time between toggling the led and turning on a different LED.**
**Exercise: Connect to the pyboard directly, create a pyb.LED object and turn it on using the on() method.**
A Disco on your pyboard
-----------------------
So far we have only used a single LED but the pyboard has 4 available. Let's start by creating an object for each LED so we can control each of them. We do that by creating a list of LEDS with a list comprehension. ::
leds = [pyb.LED(i) for i in range(1,5)]
If you call pyb.LED() with a number that isn't 1,2,3,4 you will get an error message.
Next we will set up an infinite loop that cycles through each of the LEDs turning them on and off. ::
n = 0
while True:
n = (n + 1) % 4
leds[n].toggle()
pyb.delay(50)
Here, n keeps track of the current LED and every time the loop is executed we cycle to the next n (the % sign is a modulus operator that keeps n between 0 and 4.) Then we access the nth LED and toggle it. If you run this you should see each of the LEDs turning on then all turning off again in sequence.
One problem you might find is that if you stop the script and then start it again that the LEDs are stuck on from the previous run, ruining our carefully choreographed disco. We can fix this by turning all the LEDs off when we initialise the script and then using a try/finally block. When you press CTRL-C, Micro Python generates a VCPInterrupt exception. Exceptions normally mean something has gone wrong and you can use a try: command to "catch" an exception. In this case it is just the user interrupting the script, so we don't need to catch the error but just tell Micro Python what to do when we exit. The finally block does this, and we use it to make sure all the LEDs are off. The full code is::
leds = [pyb.LED(i) for i in range(1,5)]
for l in leds:
l.off()
n = 0
try:
while True:
n = (n + 1) % 4
leds[n].toggle()
pyb.delay(50)
finally:
for l in leds:
l.off()
The Fourth Special LED
----------------------
The blue LED is special. As well as turning it on and off, you can control the intensity using the intensity() method. This takes a number between 0 and 255 that determines how bright it is. The following script makes the blue LED gradually brighter then turns it off again. ::
led = pyb.LED(4)
intensity = 0
while True:
intensity = (intensity + 1) % 255
led.intensity(intensity)
pyb.delay(20)
You can call intensity() on the other LEDs but they can only be off or on. 0 sets them off and any other number up to 255 turns them on.

107
docs/tutorial/repl.rst Normal file
View File

@@ -0,0 +1,107 @@
Getting a Micro Python REPL prompt
==================================
REPL stands for Read Evaluate Print Loop, and is the name given to the
interactive Micro Python prompt that you can access on the pyboard. Using
the REPL is by far the easiest way to test out your code and run commands.
You can use the REPL in addition to writing scripts in ``main.py``.
To use the REPL, you must connect to the serial USB device on the pyboard.
How you do this depends on your operating system.
Windows
-------
You need to install the pyboard driver to use the serial USB device.
The driver is on the pyboard's USB flash drive, and is called ``pybcdc.inf``.
To install this driver you need to go to Device Manager
for your computer, find the pyboard in the list of devices (it should have
a warning sign next to it because it's not working yet), right click on
the pyboard device, select Properties, then Install Driver. You need to
then select the option to find the driver manually (don't use Windows auto update),
navigate to the pyboard's USB drive, and select that. It should then install.
After installing, go back to the Device Manager to find the installed pyboard,
and see which COM port it is (eg COM4).
You now need to run your terminal program. You can use HyperTerminal if you
have it installed, or download the free program PuTTY:
[`putty.exe`](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html).
Using your serial program you must connect to the COM port that you found in the
previous step. With PuTTY, click on "Session" in the left-hand panel, then click
the "Serial" radio button on the right, then enter you COM port (eg COM4) in the
"Serial Line" box. Finally, click the "Open" button.
Mac OS X
--------
Open a terminal and run::
screen /dev/tty.usbmodem*
When you are finishend and want to exit screen, type CTRL-A CTRL-\\.
Linux
-----
Open a terminal and run::
screen /dev/ttyACM0
You can also try ``picocom`` or ``minicom`` instead of screen. You may have to
use ``/dev/ttyACM1`` or a higher number for ``ttyACM``. And, you may need to give
yourself the correct permissions to access this devices (eg group ``uucp`` or ``dialout``,
or use sudo).
Using the REPL prompt
---------------------
Now let's try running some Micro Python code directly on the pyboard.
With your serial program open (PuTTY, screen, picocom, etc) you may see a blank
screen with a flashing cursor. Press Enter and you should be presented with a
Micro Python prompt, i.e. ``>>>``. Let's make sure it is working with the obligatory test::
>>> print("hello pyboard!")
hello pyboard!
In the above, you should not type in the ``>>>`` characters. They are there to
indicate that you should type the text after it at the prompt. In the end, once
you have entered the text ``print("hello pyboard!")`` and pressed Enter, the output
on your screen should look like it does above.
If you already know some python you can now try some basic commands here.
If any of this is not working you can try either a hard reset or a soft reset;
see below.
Go ahead and try typing in some other commands. For example::
>>> pyb.LED(1).on()
>>> pyb.LED(2).on()
>>> 1 + 2
3
>>> 1 / 2
0.5
>>> 20 * 'py'
'pypypypypypypypypypypypypypypypypypypypy'
Resetting the board
-------------------
If something goes wrong, you can reset the board in two ways. The first is to press CTRL-D
at the Micro Python prompt, which performs a soft reset. You will see a message something like ::
>>>
PYB: sync filesystems
PYB: soft reboot
Micro Python v1.0 on 2014-05-03; PYBv1.0 with STM32F405RG
Type "help()" for more information.
>>>
If that isn't working you can perform a hard reset (turn-it-off-and-on-again) by pressing the RST
switch (the small black button closest to the micro-USB socket on the board). This will end your
session, disconnecting whatever program (PuTTY, screen, etc) that you used to connect to the pyboard.
If you are going to do a hard-reset, it's recommended to first close your serial program and eject/unmount
the pyboard drive.

60
docs/tutorial/reset.rst Normal file
View File

@@ -0,0 +1,60 @@
Safe mode and factory reset
===========================
If something goes wrong with your pyboard, don't panic! It is almost
impossible for you to break the pyboard by programming the wrong thing.
The first thing to try is to enter safe mode: this temporarily skips
execution of ``boot.py`` and ``main.py`` and gives default USB settings.
If you have problems with the filesystem you can do a factory reset,
which restores the filesystem to its original state.
Safe mode
---------
To enter safe mode, do the following steps:
1. Connect the pyboard to USB so it powers up.
2. Hold down the USR switch.
3. While still holding down USR, press and release the RST switch.
4. The LEDs will then cycle green to orange to green+orange and back again.
5. Keep holding down USR until *only the orange LED is lit*, and then let
go of the USR switch.
6. The orange LED should flash quickly 4 times, and then turn off.
7. You are now in safe mode.
In safe mode, the ``boot.py`` and ``main.py`` files are not executed, and so
the pyboard boots up with default settings. This means you now have access
to the filesystem (the USB drive should appear), and you can edit ``boot.py``
and ``main.py`` to fix any problems.
Entering safe mode is temporary, and does not make any changes to the
files on the pyboard.
Factory reset the filesystem
----------------------------
If you pyboard's filesystem gets corrupted (for example, you forgot to
eject/unmount it), or you have some code in ``boot.py`` or ``main.py`` which
you can't escape from, then you can reset the filesystem.
Resetting the filesystem deletes all files on the internal pyboard storage
(not the SD card), and restores the files ``boot.py``, ``main.py``, ``README.txt``
and ``pybcdc.inf`` back to their original state.
To do a factory reset of the filesystem you follow a similar procedure as
you did to enter safe mode, but release USR on green+orange:
1. Connect the pyboard to USB so it powers up.
2. Hold down the USR switch.
3. While still holding down USR, press and release the RST switch.
4. The LEDs will then cycle green to orange to green+orange and back again.
5. Keep holding down USR until *both the green and orange LEDs are lit*, and
then let go of the USR switch.
6. The green and orange LEDs should flash quickly 4 times.
7. The red LED will turn on (so red, green and orange are now on).
8. The pyboard is now resetting the filesystem (this takes a few seconds).
9. The LEDs all turn off.
10. You now have a reset filesystem, and are in safe mode.
11. Press and release the RST switch to boot normally.

105
docs/tutorial/script.rst Normal file
View File

@@ -0,0 +1,105 @@
Running your first script
=========================
Let's jump right in and get a Python script running on the pyboard. After
all, that's what it's all about!
Connecting your pyboard
-----------------------
Connect your pyboard to your PC (Windows, Mac or Linux) with a micro USB cable.
There is only one way that the cable will connect, so you can't get it wrong.
<img src="/static/doc/pyboard-usb-micro.jpg" alt="pyboard with USB micro cable" style="width:200px; border:1px solid black; display:inline-block;"/>
When the pyboard is connected to your PC it will power on and enter the start up
process (the boot process). The green LED should light up for half a second or
less, and when it turns off it means the boot process has completed.
Opening the pyboard USB drive
-----------------------------
Your PC should now recognise the pyboard. It depends on the type of PC you
have as to what happens next:
- **Windows**: Your pyboard will appear as a removable USB flash drive.
Windows may automatically pop-up a window, or you may need to go there
using Explorer.
Windows will also see that the pyboard has a serial device, and it will
try to automatically configure this device. If it does, cancel the process.
We will get the serial device working in the next tutorial.
- **Mac**: Your pyboard will appear on the desktop as a removable disc.
It will probably be called "NONAME". Click on it to open the pyboard folder.
- **Linux**: Your pyboard will appear as a removable medium. On Ubuntu
it will mount automatically and pop-up a window with the pyboard folder.
On other Linux distributions, the pyboard may be mounted automatically,
or you may need to do it manually. At a terminal command line, type ``lsblk``
to see a list of connected drives, and then ``mount /dev/sdb1`` (replace ``sdb1``
with the appropriate device). You may need to be root to do this.
Okay, so you should now have the pyboard connected as a USB flash drive, and
a window (or command line) should be showing the files on the pyboard drive.
The drive you are looking at is known as ``/flash`` by the pyboard, and should contain
the following 4 files:
- [``boot.py``](/static/doc/fresh-pyboard/boot.py) -- this script is executed when the pyboard boots up. It sets
up various configuration options for the pyboard.
- [``main.py``](/static/doc/fresh-pyboard/main.py) -- this is the main script that will contain your Python program.
It is executed after ``boot.py``.
- [``README.txt``](/static/doc/fresh-pyboard/README.txt) -- this contains some very basic information about getting
started with the pyboard.
- [``pybcdc.inf``](/static/doc/fresh-pyboard/pybcdc.inf) -- this is a Windows driver file to configure the serial USB
device. More about this in the next tutorial.
Editing ``main.py``
-------------------
Now we are going to write our Python program, so open the ``main.py``
file in a text editor. On Windows you can use notepad, or any other editor.
On Mac and Linux, use your favourite text editor. With the file open you will
see it contains 1 line::
# main.py -- put your code here!
This line starts with a # character, which means that it is a *comment*. Such
lines will not do anything, and are there for you to write notes about your
program.
Let's add 2 lines to this ``main.py`` file, to make it look like this::
# main.py -- put your code here!
import pyb
pyb.LED(4).on()
The first line we wrote says that we want to use the ``pyb`` module.
This module contains all the functions and classes to control the features
of the pyboard.
The second line that we wrote turns the blue LED on: it first gets the ``LED``
class from the ``pyb`` module, creates LED number 4 (the blue LED), and then
turns it on.
Resetting the pyboard
---------------------
To run this little script, you need to first save and close the ``main.py`` file,
and then eject (or unmount) the pyboard USB drive. Do this like you would a
normal USB flash drive.
When the drive is safely ejected/unmounted you can get to the fun part:
press the RST switch on the pyboard to reset and run your script. The RST
switch is the small black button just below the USB connector on the board,
on the right edge.
When you press RST the green LED will flash quickly, and then the blue
LED should turn on and stay on.
Congratulations! You have written and run your very first Micro Python
program!

146
docs/tutorial/servo.rst Normal file
View File

@@ -0,0 +1,146 @@
Controlling hobby servo motors
==============================
There are 4 dedicated connection points on the pyboard for connecting up
hobby servo motors (see eg
[Wikipedia](http://en.wikipedia.org/wiki/Servo_%28radio_control%29)).
These motors have 3 wires: ground, power and signal. On the pyboard you
can connect them in the bottom right corner, with the signal pin on the
far right. Pins X1, X2, X3 and X4 are the 4 dedicated servo signal pins.
<img src="/static/doc/pyboard-servo.jpg" alt="pyboard with servo motors" style="width:250px; border:1px solid black; display:inline-block;"/>
In this picture there are male-male double adaptors to connect the servos
to the header pins on the pyboard.
The ground wire on a servo is usually the darkest coloured one, either
black or dark brown. The power wire will most likely be red.
The power pin for the servos (labelled VIN) is connected directly to the
input power source of the pyboard. When powered via USB, VIN is powered
through a diode by the 5V USB power line. Connect to USB, the pyboard can
power at least 4 small to medium sized servo motors.
If using a battery to power the pyboard and run servo motors, make sure it
is not greater than 6V, since this is the maximum voltage most servo motors
can take. (Some motors take only up to 4.8V, so check what type you are
using.)
Creating a Servo object
-----------------------
Plug in a servo to position 1 (the one with pin X1) and create a servo object
using::
>>> servo1 = pyb.Servo(1)
To change the angle of the servo use the ``angle`` method::
>>> servo1.angle(45)
>>> servo1.angle(-60)
The angle here is measured in degrees, and ranges from about -90 to +90,
depending on the motor. Calling ``angle`` without parameters will return
the current angle::
>>> servo1.angle()
-60
Note that for some angles, the returned angle is not exactly the same as
the angle you set, due to rounding errors in setting the pulse width.
You can pass a second parameter to the ``angle`` method, which specifies how
long to take (in milliseconds) to reach the desired angle. For example, to
take 1 second (1000 milliseconds) to go from the current position to 50 degrees,
use ::
>>> servo1.angle(50, 1000)
This command will return straight away and the servo will continue to move
to the desired angle, and stop when it gets there. You can use this feature
as a speed control, or to synchronise 2 or more servo motors. If we have
another servo motor (``servo2 = pyb.Servo(2)``) then we can do ::
>>> servo1.angle(-45, 2000); servo2.angle(60, 2000)
This will move the servos together, making them both take 2 seconds to
reach their final angles.
Note: the semicolon between the 2 expressions above is used so that they
are executed one after the other when you press enter at the REPL prompt.
In a script you don't need to do this, you can just write them one line
after the other.
Continuous rotation servos
--------------------------
So far we have been using standard servos that move to a specific angle
and stay at that angle. These servo motors are useful to create joints
of a robot, or things like pan-tilt mechanisms. Internally, the motor
has a variable resistor (potentiometer) which measures the current angle
and applies power to the motor proportional to how far it is from the
desired angle. The desired angle is set by the width of a high-pulse on
the servo signal wire. A pulse width of 1500 microsecond corresponds
to the centre position (0 degrees). The pulses are sent at 50 Hz, ie
50 pulses per second.
You can also get **continuous rotation** servo motors which turn
continuously clockwise or counterclockwise. The direction and speed of
rotation is set by the pulse width on the signal wire. A pulse width
of 1500 microseconds corresponds to a stopped motor. A pulse width
smaller or larger than this means rotate one way or the other, at a
given speed.
On the pyboard, the servo object for a continuous rotation motor is
the same as before. In fact, using ``angle`` you can set the speed. But
to make it easier to understand what is intended, there is another method
called ``speed`` which sets the speed::
>>> servo1.speed(30)
``speed`` has the same functionality as ``angle``: you can get the speed,
set it, and set it with a time to reach the final speed. ::
>>> servo1.speed()
30
>>> servo1.speed(-20)
>>> servo1.speed(0, 2000)
The final command above will set the motor to stop, but take 2 seconds
to do it. This is essentially a control over the acceleration of the
continuous servo.
A servo speed of 100 (or -100) is considered maximum speed, but actually
you can go a bit faster than that, depending on the particular motor.
The only difference between the ``angle`` and ``speed`` methods (apart from
the name) is the way the input numbers (angle or speed) are converted to
a pulse width.
Calibration
-----------
The conversion from angle or speed to pulse width is done by the servo
object using its calibration values. To get the current calibration,
use ::
>>> servo1.calibration()
(640, 2420, 1500, 2470, 2200)
There are 5 numbers here, which have meaning:
1. Minimum pulse width; the smallest pulse width that the servo accepts.
2. Maximum pulse width; the largest pulse width that the servo accepts.
3. Centre pulse width; the pulse width that puts the servo at 0 degrees
or 0 speed.
4. The pulse width corresponding to 90 degrees. This sets the conversion
in the method ``angle`` of angle to pulse width.
5. The pulse width corresponding to a speed of 100. This sets the conversion
in the method ``speed`` of speed to pulse width.
You can recalibrate the servo (change its default values) by using::
>>> servo1.calibration(700, 2400, 1510, 2500, 2000)
Of course, you would change the above values to suit your particular
servo motor.

101
docs/tutorial/switch.rst Normal file
View File

@@ -0,0 +1,101 @@
The Switch, callbacks and interrupts
====================================
The pyboard has 2 small switches, labelled USR and RST. The RST switch
is a hard-reset switch, and if you press it then it restarts the pyboard
from scratch, equivalent to turning the power off then back on.
The USR switch is for general use, and is controlled via a Switch object.
To make a switch object do::
>>> sw = pyb.Switch()
Remember that you may need to type ``import pyb`` if you get an error that
the name ``pyb`` does not exist.
With the switch object you can get its status::
>>> sw()
False
This will print ``False`` if the switch is not held, or ``True`` if it is held.
Try holding the USR switch down while running the above command.
Switch callbacks
----------------
The switch is a very simple object, but it does have one advanced feature:
the ``sw.callback()`` function. The callback function sets up something to
run when the switch is pressed, and uses an interrupt. It's probably best
to start with an example before understanding how interrupts work. Try
running the following at the prompt::
>>> sw.callback(lambda:print('press!'))
This tells the switch to print ``press!`` each time the switch is pressed
down. Go ahead and try it: press the USR switch and watch the output on
your PC. Note that this print will interrupt anything you are typing, and
is an example of an interrupt routine running asynchronously.
As another example try::
>>> sw.callback(lambda:pyb.LED(1).toggle())
This will toggle the red LED each time the switch is pressed. And it will
even work while other code is running.
To disable the switch callback, pass ``None`` to the callback function::
>>> sw.callback(None)
You can pass any function (that takes zero arguments) to the switch callback.
Above we used the ``lambda`` feature of Python to create an anonymous function
on the fly. But we could equally do::
>>> def f():
... pyb.LED(1).toggle()
...
>>> sw.callback(f)
This creates a function called ``f`` and assigns it to the switch callback.
You can do things this way when your function is more complicated than a
``lambda`` will allow.
Note that your callback functions must not allocate any memory (for example
they cannot create a tuple or list). Callback functions should be relatively
simple. If you need to make a list, make it beforehand and store it in a
global variable (or make it local and close over it). If you need to do
a long, complicated calculation, then use the callback to set a flag which
some other code then responds to.
Technical details of interrupts
-------------------------------
Let's step through the details of what is happening with the switch
callback. When you register a function with ``sw.callback()``, the switch
sets up an external interrupt trigger (falling edge) on the pin that the
switch is connected to. This means that the microcontroller will listen
on the pin for any changes, and the following will occur:
1. When the switch is pressed a change occurs on the pin (the pin goes
from low to high), and the microcontroller registers this change.
2. The microcontroller finishes executing the current machine instruction,
stops execution, and saves its current state (pushes the registers on
the stack). This has the effect of pausing any code, for example your
running Python script.
3. The microcontroller starts executing the special interrupt handler
associated with the switch's external trigger. This interrupt handler
get the function that you registered with ``sw.callback()`` and executes
it.
4. Your callback function is executed until it finishes, returning control
to the switch interrupt handler.
5. The switch interrupt handler returns, and the microcontroller is
notified that the interrupt has been dealt with.
6. The microcontroller restores the state that it saved in step 2.
7. Execution continues of the code that was running at the beginning. Apart
from the pause, this code does not notice that it was interrupted.
The above sequence of events gets a bit more complicated when multiple
interrupts occur at the same time. In that case, the interrupt with the
highest priority goes first, then the others in order of their priority.
The switch interrupt is set at the lowest priority.

112
docs/tutorial/timer.rst Normal file
View File

@@ -0,0 +1,112 @@
The Timers
==========
The pyboard has 14 timers which each consist of an independent counter
running at a user-defined frequency. They can be set up to run a function
at specific intervals.
The 14 timers are numbered 1 through 14, but 3 is reserved
for internal use, and 5 and 6 are used for servo and ADC/DAC control.
Avoid using these timers if possible.
Let's create a timer object::
>>> tim = pyb.Timer(4)
Now let's see what we just created::
>>> tim
Timer(4)
The pyboard is telling us that ``tim`` is attached to timer number 4, but
it's not yet initialised. So let's initialise it to trigger at 10 Hz
(that's 10 times per second)::
>>> tim.init(freq=10)
Now that it's initialised, we can see some information about the timer::
>>> tim
Timer(4, prescaler=255, period=32811, mode=0, div=0)
The information means that this timer is set to run at the peripheral
clock speed divided by 255, and it will count up to 32811, at which point
it triggers an interrupt, and then starts counting again from 0. These
numbers are set to make the timer trigger at 10 Hz.
Timer counter
-------------
So what can we do with our timer? The most basic thing is to get the
current value of its counter::
>>> tim.counter()
21504
This counter will continuously change, and counts up.
Timer callbacks
---------------
The next thing we can do is register a callback function for the timer to
execute when it triggers (see the [switch tutorial](tut-switch) for an
introduction to callback functions)::
>>> tim.callback(lambda t:pyb.LED(1).toggle())
This should start the red LED flashing right away. It will be flashing
at 5 Hz (2 toggle's are needed for 1 flash, so toggling at 10 Hz makes
it flash at 5 Hz). You can change the frequency by re-initialising the
timer::
>>> tim.init(freq=20)
You can disable the callback by passing it the value ``None``::
>>> tim.callback(None)
The function that you pass to callback must take 1 argument, which is
the timer object that triggered. This allows you to control the timer
from within the callback function.
We can create 2 timers and run them independently::
>>> tim4 = pyb.Timer(4, freq=10)
>>> tim7 = pyb.Timer(7, freq=20)
>>> tim4.callback(lambda t: pyb.LED(1).toggle())
>>> tim7.callback(lambda t: pyb.LED(2).toggle())
Because the callbacks are proper hardware interrupts, we can continue
to use the pyboard for other things while these timers are running.
Making a microsecond counter
----------------------------
You can use a timer to create a microsecond counter, which might be
useful when you are doing something which requires accurate timing.
We will use timer 2 for this, since timer 2 has a 32-bit counter (so
does timer 5, but if you use timer 5 then you can't use the Servo
driver at the same time).
We set up timer 2 as follows::
>>> micros = pyb.Timer(2, prescaler=83, period=0x3fffffff)
The prescaler is set at 83, which makes this timer count at 1 MHz.
This is because the CPU clock, running at 168 MHz, is divided by
2 and then by prescaler+1, giving a freqency of 168 MHz/2/(83+1)=1 MHz
for timer 2. The period is set to a large number so that the timer
can count up to a large number before wrapping back around to zero.
In this case it will take about 17 minutes before it cycles back to
zero.
To use this timer, it's best to first reset it to 0::
>>> micros.counter(0)
and then perform your timing::
>>> start_micros = micros.counter()
... do some stuff ...
>>> end_micros = micros.counter()

129
docs/tutorial/usb_mouse.rst Normal file
View File

@@ -0,0 +1,129 @@
Making the pyboard act as a USB mouse
=====================================
The pyboard is a USB device, and can configured to act as a mouse instead
of the default USB flash drive.
To do this we must first edit the ``boot.py`` file to change the USB
configuration. If you have not yet touched your ``boot.py`` file then it
will look something like this::
# boot.py -- run on boot-up
# can run arbitrary Python, but best to keep it minimal
import pyb
#pyb.main('main.py') # main script to run after this one
#pyb.usb_mode('CDC+MSC') # act as a serial and a storage device
#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
To enable the mouse mode, uncomment the last line of the file, to
make it look like::
pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
If you already changed your ``boot.py`` file, then the minimum code it
needs to work is::
import pyb
pyb.usb_mode('CDC+HID')
This tells the pyboard to configure itself as a CDC (serial) and HID
(human interface device, in our case a mouse) USB device when it boots
up.
Eject/unmount the pyboard drive and reset it using the RST switch.
Your PC should now detect the pyboard as a mouse!
Sending mouse events by hand
----------------------------
To get the py-mouse to do anything we need to send mouse events to the PC.
We will first do this manually using the REPL prompt. Connect to your
pyboard using your serial program and type the following::
>>> pyb.hid((0, 10, 0, 0))
Your mouse should move 10 pixels to the right! In the command above you
are sending 4 pieces of information: button status, x, y and scroll. The
number 10 is telling the PC that the mouse moved 10 pixels in the x direction.
Let's make the mouse oscillate left and right::
>>> import math
>>> def osc(n, d):
... for i in range(n):
... pyb.hid((0, int(20 * math.sin(i / 10)), 0, 0))
... pyb.delay(d)
...
>>> osc(100, 50)
The first argument to the function ``osc`` is the number of mouse events to send,
and the second argument is the delay (in milliseconds) between events. Try
playing around with different numbers.
**Excercise: make the mouse go around in a circle.**
Making a mouse with the accelerometer
-------------------------------------
Now lets make the mouse move based on the angle of the pyboard, using the
accelerometer. The following code can be typed directly at the REPL prompt,
or put in the ``main.py`` file. Here, we'll put in in ``main.py`` because to do
that we will learn how to go into safe mode.
At the moment the pyboard is acting as a serial USB device and an HID (a mouse).
So you cannot access the filesystem to edit your ``main.py`` file.
You also can't edit your ``boot.py`` to get out of HID-mode and back to normal
mode with a USB drive...
To get around this we need to go into *safe mode*. This was described in
the [safe mode tutorial](tut-reset), but we repeat the instructions here:
1. Hold down the USR switch.
2. While still holding down USR, press and release the RST switch.
3. The LEDs will then cycle green to orange to green+orange and back again.
4. Keep holding down USR until *only the orange LED is lit*, and then let
go of the USR switch.
5. The orange LED should flash quickly 4 times, and then turn off.
6. You are now in safe mode.
In safe mode, the ``boot.py`` and ``main.py`` files are not executed, and so
the pyboard boots up with default settings. This means you now have access
to the filesystem (the USB drive should appear), and you can edit ``main.py``.
(Leave ``boot.py`` as-is, because we still want to go back to HID-mode after
we finish editting ``main.py``.)
In ``main.py`` put the following code::
import pyb
switch = pyb.Switch()
accel = pyb.Accel()
while not switch():
pyb.hid((0, accel.x(), accel.y(), 0))
pyb.delay(20)
Save your file, eject/unmount your pyboard drive, and reset it using the RST
switch. It should now act as a mouse, and the angle of the board will move
the mouse around. Try it out, and see if you can make the mouse stand still!
Press the USR switch to stop the mouse motion.
You'll note that the y-axis is inverted. That's easy to fix: just put a
minus sign in front of the y-coordinate in the ``pyb.hid()`` line above.
Restoring your pyboard to normal
--------------------------------
If you leave your pyboard as-is, it'll behave as a mouse everytime you plug
it in. You probably want to change it back to normal. To do this you need
to first enter safe mode (see above), and then edit the ``boot.py`` file.
In the ``boot.py`` file, comment out (put a # in front of) the line with the
``CDC+HID`` setting, so it looks like::
#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse
Save your file, eject/unmount the drive, and reset the pyboard. It is now
back to normal operating mode.

2
drivers/README.md Normal file
View File

@@ -0,0 +1,2 @@
This directory contains drivers for specific hardware. The drivers are
intended to work across multiple ports.

View File

@@ -12,32 +12,41 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __COMMON_H__
#define __COMMON_H__
#ifndef __CC3000_COMMON_H__
#define __CC3000_COMMON_H__
#include "data_types.h"
//******************************************************************************
// Include files
//******************************************************************************
#include <stdlib.h>
#include <stdint.h>
//*****************************************************************************
// Prefix exported names to avoid name clash
//*****************************************************************************
#define CC3000_EXPORT(name) cc3000_ ## name
//*****************************************************************************
//
@@ -49,6 +58,8 @@
extern "C" {
#endif
extern int CC3000_EXPORT(errno);
//*****************************************************************************
// ERROR CODES
//*****************************************************************************
@@ -59,18 +70,16 @@ extern "C" {
//*****************************************************************************
// COMMON DEFINES
//*****************************************************************************
#define ERROR_SOCKET_INACTIVE -57
#define ERROR_SOCKET_INACTIVE -57
#define WLAN_ENABLE (1)
#define WLAN_ENABLE (1)
#define WLAN_DISABLE (0)
#define MAC_ADDR_LEN (6)
#define SP_PORTION_SIZE (32)
// #define CC3000_TINY_DRIVER
/*Defines for minimal and maximal RX buffer size. This size includes the spi
/*Defines for minimal and maximal RX buffer size. This size includes the spi
header and hci header.
The maximal buffer size derives from:
MTU + HCI header + SPI header + sendto() agrs size
@@ -78,26 +87,26 @@ extern "C" {
HCI header + SPI header + max args size
This buffer is used for receiving events and data.
The packet can not be longer than MTU size and CC3000 does not support
fragmentation. Note that the same buffer is used for reception of the data
and events from CC3000. That is why the minimum is defined.
The packet can not be longer than MTU size and CC3000 does not support
fragmentation. Note that the same buffer is used for reception of the data
and events from CC3000. That is why the minimum is defined.
The calculation for the actual size of buffer for reception is:
Given the maximal data size MAX_DATA that is expected to be received by
application, the required buffer is:
Using recv() or recvfrom():
max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen
+ ucArgsize + 1)
Using gethostbyname() with minimal buffer size will limit the host name
returned to 99 bytes only.
The 1 is used for the overrun detection
The 1 is used for the overrun detection
Buffer size increased to 130 following the add_profile() with WEP security
which requires TX buffer size of 130 bytes:
which requires TX buffer size of 130 bytes:
HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130
MAX SSID LEN = 32
MAX SSID LEN = 13 (with add_profile only ascii key setting is supported,
MAX SSID LEN = 32
MAX SSID LEN = 13 (with add_profile only ascii key setting is supported,
therfore maximum key size is 13)
*/
@@ -106,24 +115,24 @@ extern "C" {
/*Defines for minimal and maximal TX buffer size.
This buffer is used for sending events and data.
The packet can not be longer than MTU size and CC3000 does not support
The packet can not be longer than MTU size and CC3000 does not support
fragmentation. Note that the same buffer is used for transmission of the data
and commands. That is why the minimum is defined.
The calculation for the actual size of buffer for transmission is:
Given the maximal data size MAX_DATA, the required buffer is:
Using Sendto():
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+ SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
Using Send():
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+ HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
The 1 is used for the overrun detection */
The 1 is used for the overrun detection */
#define CC3000_MINIMAL_TX_SIZE (130 + 1)
#define CC3000_MINIMAL_TX_SIZE (130 + 1)
#define CC3000_MAXIMAL_TX_SIZE (1519 + 1)
//TX and RX buffer sizes, allow to receive and transmit maximum data at length 8.
@@ -132,64 +141,64 @@ extern "C" {
#define TINY_CC3000_MAXIMAL_TX_SIZE 59
#endif
/*In order to determine your preferred buffer size,
/*In order to determine your preferred buffer size,
change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between
the minimal and maximal specified above.
the minimal and maximal specified above.
Note that the buffers are allocated by SPI.
In case you change the size of those buffers, you might need also to change
the linker file, since for example on MSP430 FRAM devices the buffers are
allocated in the FRAM section that is allocated manually and not by IDE.
*/
#ifndef CC3000_TINY_DRIVER
#define CC3000_RX_BUFFER_SIZE (CC3000_MINIMAL_RX_SIZE)
#define CC3000_TX_BUFFER_SIZE (CC3000_MINIMAL_TX_SIZE)
#define CC3000_RX_BUFFER_SIZE (CC3000_MAXIMAL_RX_SIZE)
#define CC3000_TX_BUFFER_SIZE (CC3000_MAXIMAL_TX_SIZE)
//if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption
#else
#define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE)
#define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE)
#endif
#endif
//*****************************************************************************
// Compound Types
//*****************************************************************************
typedef long time_t;
typedef unsigned long clock_t;
typedef long suseconds_t;
typedef INT32 time_t;
typedef UINT32 clock_t;
typedef INT32 suseconds_t;
typedef struct timeval timeval;
struct timeval
struct timeval
{
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
typedef char *(*tFWPatches)(unsigned long *usLength);
typedef CHAR *(*tFWPatches)(UINT32 *usLength);
typedef char *(*tDriverPatches)(unsigned long *usLength);
typedef CHAR *(*tDriverPatches)(UINT32 *usLength);
typedef char *(*tBootLoaderPatches)(unsigned long *usLength);
typedef CHAR *(*tBootLoaderPatches)(UINT32 *usLength);
typedef void (*tWlanCB)(long event_type, char * data, unsigned char length );
typedef void (*tWlanCB)(INT32 event_type, CHAR * data, UINT8 length );
typedef long (*tWlanReadInteruptPin)(void);
typedef INT32 (*tWlanReadInteruptPin)(void);
typedef void (*tWlanInterruptEnable)(void);
typedef void (*tWlanInterruptDisable)(void);
typedef void (*tWriteWlanPin)(unsigned char val);
typedef void (*tWriteWlanPin)(UINT8 val);
typedef struct
{
unsigned short usRxEventOpcode;
unsigned short usEventOrDataReceived;
unsigned char *pucReceivedData;
unsigned char *pucTxCommandBuffer;
UINT16 usRxEventOpcode;
UINT16 usEventOrDataReceived;
UINT8 *pucReceivedData;
UINT8 *pucTxCommandBuffer;
tFWPatches sFWPatches;
tDriverPatches sDriverPatches;
@@ -200,16 +209,16 @@ typedef struct
tWlanInterruptDisable WlanInterruptDisable;
tWriteWlanPin WriteWlanPin;
signed long slTransmitDataError;
unsigned short usNumberOfFreeBuffers;
unsigned short usSlBufferLength;
unsigned short usBufferSize;
unsigned short usRxDataPending;
INT32 slTransmitDataError;
UINT16 usNumberOfFreeBuffers;
UINT16 usSlBufferLength;
UINT16 usBufferSize;
UINT16 usRxDataPending;
unsigned long NumberOfSentPackets;
unsigned long NumberOfReleasedPackets;
UINT32 NumberOfSentPackets;
UINT32 NumberOfReleasedPackets;
unsigned char InformHostOnTxComplete;
UINT8 InformHostOnTxComplete;
}sSimplLinkInformation;
extern volatile sSimplLinkInformation tSLInformation;
@@ -235,7 +244,7 @@ extern volatile sSimplLinkInformation tSLInformation;
//
//*****************************************************************************
extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams);
extern void SimpleLinkWaitEvent(UINT16 usOpcode, void *pRetParams);
//*****************************************************************************
//
@@ -248,12 +257,12 @@ extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams);
//! @return none
//!
//! @brief Wait for data, pass it to the hci_event_handler
//! and update in a global variable that there is
//! and update in a global variable that there is
//! data to read.
//
//*****************************************************************************
extern void SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from, unsigned char *fromlen);
extern void SimpleLinkWaitData(UINT8 *pBuf, UINT8 *from, UINT8 *fromlen);
//*****************************************************************************
//
@@ -269,7 +278,7 @@ extern void SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from, unsigne
//
//*****************************************************************************
extern unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32);
extern UINT8* UINT32_TO_STREAM_f (UINT8 *p, UINT32 u32);
//*****************************************************************************
//
@@ -280,12 +289,12 @@ extern unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32);
//!
//! \return pointer to the new stream
//!
//! \brief This function is used for copying 16 bit to stream
//! \brief This function is used for copying 16 bit to stream
//! while converting to little endian format.
//
//*****************************************************************************
extern unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16);
extern UINT8* UINT16_TO_STREAM_f (UINT8 *p, UINT16 u16);
//*****************************************************************************
//
@@ -296,12 +305,12 @@ extern unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16);
//!
//! \return pointer to the new 16 bit
//!
//! \brief This function is used for copying received stream to
//! \brief This function is used for copying received stream to
//! 16 bit in little endian format.
//
//*****************************************************************************
extern unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset);
extern UINT16 STREAM_TO_UINT16_f(CHAR* p, UINT16 offset);
//*****************************************************************************
//
@@ -317,21 +326,7 @@ extern unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset);
//
//*****************************************************************************
extern unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset);
//*****************************************************************************
//
//! cc3k_int_poll
//!
//! \brief checks if the interrupt pin is low
//! just in case the hardware missed a falling edge
//! function is in ccspi.cpp
//
//*****************************************************************************
extern void cc3k_int_poll();
extern UINT32 STREAM_TO_UINT32_f(CHAR* p, UINT16 offset);
//*****************************************************************************
@@ -346,14 +341,14 @@ extern void cc3k_int_poll();
//This macro is used for copying 32 bit to stream while converting to little endian format.
#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32))
//This macro is used for copying a specified value length bits (l) to stream while converting to little endian format.
#define ARRAY_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((unsigned char *) a)[_i];}
#define ARRAY_TO_STREAM(p, a, l) {register INT16 _i; for (_i = 0; _i < l; _i++) *(p)++ = ((UINT8 *) a)[_i];}
//This macro is used for copying received stream to 8 bit in little endian format.
#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (unsigned char)(*(_p + _offset));}
#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (UINT8)(*(_p + _offset));}
//This macro is used for copying received stream to 16 bit in little endian format.
#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);}
//This macro is used for copying received stream to 32 bit in little endian format.
#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);}
#define STREAM_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((unsigned char *) p)[_i];}
#define STREAM_TO_STREAM(p, a, l) {register INT16 _i; for (_i = 0; _i < l; _i++) *(a)++= ((UINT8 *) p)[_i];}
@@ -367,4 +362,4 @@ extern void cc3k_int_poll();
}
#endif // __cplusplus
#endif // __COMMON_H__
#endif // __CC3000_COMMON_H__

View File

@@ -3,14 +3,6 @@
* spi.h - CC3000 Host Driver Implementation.
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
* & Limor Fried for Adafruit Industries
* This library works with the Adafruit CC3000 breakout
* ----> https://www.adafruit.com/products/1469
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -20,40 +12,43 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __SPI_H__
#define __SPI_H__
#ifndef __CC3000_SPI_H__
#define __CC3000_SPI_H__
//#include <string.h>
//#include <stdlib.h>
//#include <stdio.h>
//#include "wlan.h"
//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*gcSpiHandleRx)(void *p);
typedef void (*gcSpiHandleTx)(void);
extern unsigned char wlan_tx_buffer[];
//*****************************************************************************
@@ -61,23 +56,30 @@ extern unsigned char wlan_tx_buffer[];
// Prototypes for the APIs.
//
//*****************************************************************************
extern void SpiInit(void);
// the arguments must be of type pin_obj_t* and SPI_HandleTypeDef*
extern void SpiInit(void *spi, const void *pin_cs, const void *pin_en, const void *pin_irq);
extern void SpiOpen(gcSpiHandleRx pfRxHandler);
extern void SpiClose(void);
extern void SpiPauseSpi(void);
extern void SpiResumeSpi(void);
extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength);
extern void SpiResumeSpi(void);
extern void SpiConfigureHwMapping(void);
extern void SpiCleanGPIOISR(void);
extern long TXBufferIsEmpty(void);
extern long RXBufferIsEmpty(void);
extern void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length);
extern void WriteWlanPin( unsigned char val );
extern void SSIConfigure(unsigned long ulSSIFreq, unsigned long bForceGpioConfiguration, unsigned long uiReconfigureSysClock);
extern int init_spi(void);
extern long ReadWlanInterruptPin(void);
extern void WlanInterruptEnable();
extern void WlanInterruptDisable();
extern char *sendDriverPatch(unsigned long *Length);
extern char *sendBootLoaderPatch(unsigned long *Length);
extern char *sendWLFWPatch(unsigned long *Length);
extern void SpiIntGPIOHandler(void);
extern void WriteWlanPin(unsigned char val);
//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif // __cplusplus
#endif

View File

@@ -0,0 +1,107 @@
/*****************************************************************************
*
* data_types.h - CC3000 Host Driver Implementation.
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __CC3000_DATA_TYPES__
#define __CC3000_DATA_TYPES__
//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NULL
#define NULL (0)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
#ifndef OK
#define OK (0)
#endif
#ifndef _INT8
#define _INT8
typedef signed char INT8;
#endif
#ifndef _UINT8
#define _UINT8
typedef unsigned char UINT8;
#endif
#ifndef _INT16
#define _INT16
typedef signed short INT16;
#endif
#ifndef _UINT16
#define _UINT16
typedef unsigned short UINT16;
#endif
#ifndef _BOOLEAN
#define _BOOLEAN
typedef unsigned char BOOLEAN;
#endif
#ifndef _INT32
#define _INT32
typedef signed long INT32;
#endif
#ifndef _UINT32
#define _UINT32
typedef unsigned long UINT32;
#endif
typedef int INT;
typedef char CHAR;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CC3000_DATA_TYPES__ */

View File

@@ -12,28 +12,28 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __EVENT_HANDLER_H__
#define __EVENT_HANDLER_H__
#ifndef __CC3000_EVENT_HANDLER_H__
#define __CC3000_EVENT_HANDLER_H__
#include "hci.h"
#include "socket.h"
@@ -67,7 +67,7 @@ extern "C" {
//! event handler from global array of handlers pointers
//
//*****************************************************************************
extern unsigned char *hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen);
extern UINT8 *hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen);
//*****************************************************************************
//
@@ -81,7 +81,7 @@ extern unsigned char *hci_event_handler(void *pRetParams, unsigned char *from, u
//! @brief Handle unsolicited events
//
//*****************************************************************************
extern long hci_unsol_event_handler(char *event_hdr);
extern INT32 hci_unsol_event_handler(CHAR *event_hdr);
//*****************************************************************************
//
@@ -91,13 +91,13 @@ extern long hci_unsol_event_handler(char *event_hdr);
//!
//! @return ESUCCESS if successful, EFAIL if an error occurred
//!
//! @brief Parse the incoming unsolicited event packets and issues
//! @brief Parse the incoming unsolicited event packets and issues
//! corresponding event handler.
//
//*****************************************************************************
extern long hci_unsolicited_event_handler(void);
extern INT32 hci_unsolicited_event_handler(void);
#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((char *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((CHAR *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
#define SOCKET_STATUS_ACTIVE 0
#define SOCKET_STATUS_INACTIVE 1
@@ -107,25 +107,25 @@ extern long hci_unsolicited_event_handler(void);
#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
extern unsigned long socket_active_status;
extern UINT32 socket_active_status;
extern void set_socket_active_status(long Sd, long Status);
extern long get_socket_active_status(long Sd);
extern void set_socket_active_status(INT32 Sd, INT32 Status);
extern INT32 get_socket_active_status(INT32 Sd);
typedef struct _bsd_accept_return_t
{
long iSocketDescriptor;
long iStatus;
INT32 iSocketDescriptor;
INT32 iStatus;
sockaddr tSocketAddress;
} tBsdReturnParams;
typedef struct _bsd_read_return_t
{
long iSocketDescriptor;
long iNumberOfBytes;
unsigned long uiFlags;
INT32 iSocketDescriptor;
INT32 iNumberOfBytes;
UINT32 uiFlags;
} tBsdReadReturnParams;
#define BSD_RECV_FROM_FROMLEN_OFFSET (4)
@@ -134,23 +134,23 @@ typedef struct _bsd_read_return_t
typedef struct _bsd_select_return_t
{
long iStatus;
unsigned long uiRdfd;
unsigned long uiWrfd;
unsigned long uiExfd;
INT32 iStatus;
UINT32 uiRdfd;
UINT32 uiWrfd;
UINT32 uiExfd;
} tBsdSelectRecvParams;
typedef struct _bsd_getsockopt_return_t
{
unsigned char ucOptValue[4];
char iStatus;
UINT8 ucOptValue[4];
CHAR iStatus;
} tBsdGetSockOptReturnParams;
typedef struct _bsd_gethostbyname_return_t
{
long retVal;
long outputAddress;
INT32 retVal;
INT32 outputAddress;
} tBsdGethostbynameParams;
//*****************************************************************************
@@ -162,5 +162,5 @@ typedef struct _bsd_gethostbyname_return_t
}
#endif // __cplusplus
#endif // __EVENT_HANDLER_H__
#endif // __CC3000_EVENT_HANDLER_H__

View File

@@ -12,28 +12,28 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __HCI_H__
#define __HCI_H__
#ifndef __CC3000_HCI_H__
#define __CC3000_HCI_H__
#include "cc3000_common.h"
@@ -102,6 +102,7 @@ extern "C" {
#define HCI_CMND_RECVFROM 0x100D
#define HCI_CMND_GETHOSTNAME 0x1010
#define HCI_CMND_MDNS_ADVERTISE 0x1011
#define HCI_CMND_GETMSSVALUE 0x1012
#define HCI_DATA_BASE 0x80
@@ -167,6 +168,7 @@ extern "C" {
#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT
#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME
#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE
#define HCI_EVNT_GETMSSVALUE HCI_CMND_GETMSSVALUE
#define HCI_EVNT_SEND 0x1003
#define HCI_EVNT_WRITE 0x100E
@@ -230,8 +232,8 @@ extern "C" {
#define HCI_EVENT_LENGTH_OFFSET (3)
#define HCI_EVENT_STATUS_OFFSET (4)
#define HCI_DATA_LENGTH_OFFSET (3)
//*****************************************************************************
@@ -253,10 +255,10 @@ extern "C" {
//! @brief Initiate an HCI command.
//
//*****************************************************************************
extern unsigned short hci_command_send(unsigned short usOpcode,
unsigned char *ucArgs,
unsigned char ucArgsLength);
extern UINT16 hci_command_send(UINT16 usOpcode,
UINT8 *ucArgs,
UINT8 ucArgsLength);
//*****************************************************************************
//
@@ -273,12 +275,12 @@ extern unsigned short hci_command_send(unsigned short usOpcode,
//! @brief Initiate an HCI data write operation
//
//*****************************************************************************
extern long hci_data_send(unsigned char ucOpcode,
unsigned char *ucArgs,
unsigned short usArgsLength,
unsigned short usDataLength,
const unsigned char *ucTail,
unsigned short usTailLength);
extern INT32 hci_data_send(UINT8 ucOpcode,
UINT8 *ucArgs,
UINT16 usArgsLength,
UINT16 usDataLength,
const UINT8 *ucTail,
UINT16 usTailLength);
//*****************************************************************************
@@ -295,8 +297,8 @@ extern long hci_data_send(unsigned char ucOpcode,
//! @brief Prepare HCI header and initiate an HCI data write operation
//
//*****************************************************************************
extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
unsigned char ucArgsLength, unsigned short ucDataLength);
extern void hci_data_command_send(UINT16 usOpcode, UINT8 *pucBuff,
UINT8 ucArgsLength, UINT16 ucDataLength);
//*****************************************************************************
//
@@ -304,7 +306,7 @@ extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuf
//!
//! @param usOpcode command operation code
//! @param pucBuff pointer to the command's arguments buffer
//! @param patch pointer to patch content buffer
//! @param patch pointer to patch content buffer
//! @param usDataLength data length
//!
//! @return none
@@ -312,7 +314,7 @@ extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuf
//! @brief Prepare HCI header and initiate an HCI patch write operation
//
//*****************************************************************************
extern void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength);
extern void hci_patch_send(UINT8 ucOpcode, UINT8 *pucBuff, CHAR *patch, UINT16 usDataLength);
@@ -325,4 +327,4 @@ extern void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char
}
#endif // __cplusplus
#endif // __HCI_H__
#endif // __CC3000_HCI_H__

View File

@@ -12,44 +12,29 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __HOST_DRIVER_VERSION_H__
#define __HOST_DRIVER_VERSION_H__
#define DRIVER_VERSION_NUMBER 14
#endif // __VERSION_H__
#ifndef __CC3000_HOST_DRIVER_VERSION_H__
#define __CC3000_HOST_DRIVER_VERSION_H__
#define DRIVER_VERSION_NUMBER 15
#endif // __CC3000_HOST_DRIVER_VERSION_H__

View File

@@ -0,0 +1,4 @@
#ifndef __INET_NTOP_H
#define __INET_NTOP_H
char *inet_ntop(int af, const void *addr, char *buf, size_t size);
#endif /* __INET_NTOP_H */

View File

@@ -0,0 +1,4 @@
#ifndef __INET_PTON_H
#define __INET_PTON_H
int inet_pton(int, const char *, void *);
#endif /* __INET_PTON_H */

View File

@@ -12,29 +12,30 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __NETAPP_H__
#define __NETAPP_H__
#ifndef __CC3000_NETAPP_H__
#define __CC3000_NETAPP_H__
#include "data_types.h"
//*****************************************************************************
//
@@ -55,33 +56,33 @@ extern "C" {
typedef struct _netapp_dhcp_ret_args_t
{
unsigned char aucIP[4];
unsigned char aucSubnetMask[4];
unsigned char aucDefaultGateway[4];
unsigned char aucDHCPServer[4];
unsigned char aucDNSServer[4];
UINT8 aucIP[4];
UINT8 aucSubnetMask[4];
UINT8 aucDefaultGateway[4];
UINT8 aucDHCPServer[4];
UINT8 aucDNSServer[4];
}tNetappDhcpParams;
typedef struct _netapp_ipconfig_ret_args_t
{
unsigned char aucIP[4];
unsigned char aucSubnetMask[4];
unsigned char aucDefaultGateway[4];
unsigned char aucDHCPServer[4];
unsigned char aucDNSServer[4];
unsigned char uaMacAddr[6];
unsigned char uaSSID[32];
UINT8 aucIP[4];
UINT8 aucSubnetMask[4];
UINT8 aucDefaultGateway[4];
UINT8 aucDHCPServer[4];
UINT8 aucDNSServer[4];
UINT8 uaMacAddr[6];
UINT8 uaSSID[32];
}tNetappIpconfigRetArgs;
/*Ping send report parameters*/
typedef struct _netapp_pingreport_args
{
unsigned long packets_sent;
unsigned long packets_received;
unsigned long min_round_time;
unsigned long max_round_time;
unsigned long avg_round_time;
UINT32 packets_sent;
UINT32 packets_received;
UINT32 min_round_time;
UINT32 max_round_time;
UINT32 avg_round_time;
} netapp_pingreport_args_t;
@@ -89,45 +90,45 @@ typedef struct _netapp_pingreport_args
//
//! netapp_config_mac_adrress
//!
//! @param mac device mac address, 6 bytes. Saved: yes
//! @param mac device mac address, 6 bytes. Saved: yes
//!
//! @return return on success 0, otherwise error.
//!
//! @brief Configure device MAC address and store it in NVMEM.
//! @brief Configure device MAC address and store it in NVMEM.
//! The value of the MAC address configured through the API will
//! be stored in CC3000 non volatile memory, thus preserved
//! be stored in CC3000 non volatile memory, thus preserved
//! over resets.
//
//*****************************************************************************
extern long netapp_config_mac_adrress( unsigned char *mac );
extern INT32 netapp_config_mac_adrress( UINT8 *mac );
//*****************************************************************************
//
//! netapp_dhcp
//!
//! @param aucIP device mac address, 6 bytes. Saved: yes
//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes
//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes
//! @param aucDNSServer device mac address, 6 bytes. Saved: yes
//! @param aucIP device mac address, 6 bytes. Saved: yes
//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes
//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes
//! @param aucDNSServer device mac address, 6 bytes. Saved: yes
//!
//! @return return on success 0, otherwise error.
//!
//! @brief netapp_dhcp is used to configure the network interface,
//! static or dynamic (DHCP).\n In order to activate DHCP mode,
//! @brief netapp_dhcp is used to configure the network interface,
//! static or dynamic (DHCP).\n In order to activate DHCP mode,
//! aucIP, aucSubnetMask, aucDefaultGateway must be 0.
//! The default mode of CC3000 is DHCP mode.
//! Note that the configuration is saved in non volatile memory
//! and thus preserved over resets.
//!
//! @note If the mode is altered a reset of CC3000 device is required
//! in order to apply changes.\nAlso note that asynchronous event
//! of DHCP_EVENT, which is generated when an IP address is
//! allocated either by the DHCP server or due to static
//! allocation is generated only upon a connection to the
//! AP was established.
//!
//! @note If the mode is altered a reset of CC3000 device is required
//! in order to apply changes.\nAlso note that asynchronous event
//! of DHCP_EVENT, which is generated when an IP address is
//! allocated either by the DHCP server or due to static
//! allocation is generated only upon a connection to the
//! AP was established.
//!
//*****************************************************************************
extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer);
extern INT32 netapp_dhcp(UINT32 *aucIP, UINT32 *aucSubnetMask,UINT32 *aucDefaultGateway, UINT32 *aucDNSServer);
@@ -135,30 +136,30 @@ extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsi
//
//! netapp_timeout_values
//!
//! @param aucDHCP DHCP lease time request, also impact
//! @param aucDHCP DHCP lease time request, also impact
//! the DHCP renew timeout. Range: [0-0xffffffff] seconds,
//! 0 or 0xffffffff == infinity lease timeout.
//! Resolution:10 seconds. Influence: only after
//! reconnecting to the AP.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
//! The parameter is saved into the CC3000 NVMEM.
//! Resolution:10 seconds. Influence: only after
//! reconnecting to the AP.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds.
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 14400 seconds.
//!
//!
//! @param aucARP ARP refresh timeout, if ARP entry is not updated by
//! incoming packet, the ARP entry will be deleted by
//! the end of the timeout.
//! the end of the timeout.
//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
//! Resolution: 10 seconds. Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds
//! The parameter is saved into the CC3000 NVMEM.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 3600 seconds.
//!
//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout
//! Range: [0-0xffffffff] seconds, 0 == infinity timeout
//! Resolution: 10 seconds.
//! Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
//! The parameter is saved into the CC3000 NVMEM.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 10 seconds.
//!
//! @param aucInactivity Socket inactivity timeout, socket timeout is
@@ -166,22 +167,22 @@ extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsi
//! end of the socket timeout the socket will be closed
//! Range: [0-0xffffffff] sec, 0 == infinity timeout.
//! Resolution: 10 seconds. Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
//! The parameter is saved into the CC3000 NVMEM.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 60 seconds.
//!
//! @return return on success 0, otherwise error.
//!
//! @brief Set new timeout values. Function set new timeout values for:
//! DHCP lease timeout, ARP refresh timeout, keepalive event
//! timeout and socket inactivity timeout
//!
//! @note If a parameter set to non zero value which is less than 20s,
//! it will be set automatically to 20s.
//! @brief Set new timeout values. Function set new timeout values for:
//! DHCP lease timeout, ARP refresh timeout, keepalive event
//! timeout and socket inactivity timeout
//!
//! @note If a parameter set to non zero value which is less than 10s,
//! it will be set automatically to 10s.
//!
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity);
#ifndef CC3000_TINY_DRIVER
extern INT32 netapp_timeout_values(UINT32 *aucDHCP, UINT32 *aucARP, UINT32 *aucKeepalive, UINT32 *aucInactivity);
#endif
//*****************************************************************************
@@ -190,23 +191,23 @@ extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,
//!
//! @param ip destination IP address
//! @param pingAttempts number of echo requests to send
//! @param pingSize send buffer size which may be up to 1400 bytes
//! @param pingSize send buffer size which may be up to 1400 bytes
//! @param pingTimeout Time to wait for a response,in milliseconds.
//!
//! @return return on success 0, otherwise error.
//!
//! @brief send ICMP ECHO_REQUEST to network hosts
//!
//! @note If an operation finished successfully asynchronous ping report
//! @brief send ICMP ECHO_REQUEST to network hosts
//!
//! @note If an operation finished successfully asynchronous ping report
//! event will be generated. The report structure is as defined
//! by structure netapp_pingreport_args_t.
//!
//! @warning Calling this function while a previous Ping Requests are in
//! @warning Calling this function while a previous Ping Requests are in
//! progress will stop the previous ping request.
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout);
extern INT32 netapp_ping_send(UINT32 *ip, UINT32 ulPingAttempts, UINT32 ulPingSize, UINT32 ulPingTimeout);
#endif
//*****************************************************************************
@@ -215,15 +216,15 @@ extern long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, un
//!
//! @param none
//!
//! @return On success, zero is returned. On error, -1 is returned.
//! @return On success, zero is returned. On error, -1 is returned.
//!
//! @brief Stop any ping request.
//!
//!
//!
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern long netapp_ping_stop();
extern INT32 netapp_ping_stop();
#endif
//*****************************************************************************
//
@@ -233,7 +234,7 @@ extern long netapp_ping_stop();
//!
//! @return none
//!
//! @brief Request for ping status. This API triggers the CC3000 to send
//! @brief Request for ping status. This API triggers the CC3000 to send
//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.
//! This event will carry the report structure:
//! netapp_pingreport_args_t. This structure is filled in with ping
@@ -242,8 +243,8 @@ extern long netapp_ping_stop();
//! packets_received - echo reply, min_round_time - minimum
//! round time, max_round_time - max round time,
//! avg_round_time - average round time
//!
//! @note When a ping operation is not active, the returned structure
//!
//! @note When a ping operation is not active, the returned structure
//! fields are 0.
//!
//*****************************************************************************
@@ -256,7 +257,7 @@ extern void netapp_ping_report();
//
//! netapp_ipconfig
//!
//! @param[out] ipconfig This argument is a pointer to a
//! @param[out] ipconfig This argument is a pointer to a
//! tNetappIpconfigRetArgs structure. This structure is
//! filled in with the network interface configuration.
//! tNetappIpconfigRetArgs:\n aucIP - ip address,
@@ -271,7 +272,7 @@ extern void netapp_ping_report();
//! Note that the information is available only after the WLAN
//! connection was established. Calling this function before
//! associated, will cause non-defined values to be returned.
//!
//!
//! @note The function is useful for figuring out the IP Configuration of
//! the device when DHCP is used and for figuring out the SSID of
//! the Wireless network the device is associated with.
@@ -294,7 +295,7 @@ extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig );
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern long netapp_arp_flush();
extern INT32 netapp_arp_flush();
#endif
@@ -318,7 +319,7 @@ extern long netapp_arp_flush();
#ifndef CC3000_TINY_DRIVER
long netapp_set_debug_level(unsigned long ulLevel);
INT32 netapp_set_debug_level(UINT32 ulLevel);
#endif
//*****************************************************************************
//
@@ -338,5 +339,5 @@ long netapp_set_debug_level(unsigned long ulLevel);
}
#endif // __cplusplus
#endif // __NETAPP_H__
#endif // __CC3000_NETAPP_H__

View File

@@ -12,28 +12,28 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __NVRAM_H__
#define __NVRAM_H__
#ifndef __CC3000_NVRAM_H__
#define __CC3000_NVRAM_H__
#include "cc3000_common.h"
@@ -59,7 +59,7 @@ extern "C" {
/****************************************************************************
**
** Definitions for File IDs
**
**
****************************************************************************/
/* NVMEM file ID - system files*/
#define NVMEM_NVS_FILEID (0)
@@ -95,19 +95,19 @@ extern "C" {
//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
//! and user files 12-15.
//! @param ulLength number of bytes to read
//! @param ulOffset ulOffset in file from where to read
//! @param ulLength number of bytes to read
//! @param ulOffset ulOffset in file from where to read
//! @param buff output buffer pointer
//!
//! @return number of bytes read, otherwise error.
//! @return on success 0, error otherwise.
//!
//! @brief Reads data from the file referred by the ulFileId parameter.
//! @brief Reads data from the file referred by the ulFileId parameter.
//! Reads data from file ulOffset till length. Err if the file can't
//! be used, is invalid, or if the read is out of bounds.
//!
//! be used, is invalid, or if the read is out of bounds.
//!
//*****************************************************************************
extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsigned long offset, unsigned char *buff);
extern INT32 nvmem_read(UINT32 file_id, UINT32 length, UINT32 offset, UINT8 *buff);
//*****************************************************************************
//
@@ -117,21 +117,21 @@ extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsig
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
//! and user files 12-15.
//! @param ulLength number of bytes to write
//! @param ulEntryOffset offset in file to start write operation from
//! @param ulLength number of bytes to write
//! @param ulEntryOffset offset in file to start write operation from
//! @param buff data to write
//!
//! @return on success 0, error otherwise.
//!
//! @brief Write data to nvmem.
//! writes data to file referred by the ulFileId parameter.
//! Writes data to file ulOffset till ulLength.The file id will be
//! writes data to file referred by the ulFileId parameter.
//! Writes data to file ulOffset till ulLength.The file id will be
//! marked invalid till the write is done. The file entry doesn't
//! need to be valid - only allocated.
//!
//!
//*****************************************************************************
extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff);
extern INT32 nvmem_write(UINT32 ulFileId, UINT32 ulLength, UINT32 ulEntryOffset, UINT8 *buff);
//*****************************************************************************
@@ -142,26 +142,26 @@ extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, u
//!
//! @return on success 0, error otherwise.
//!
//! @brief Write MAC address to EEPROM.
//! @brief Write MAC address to EEPROM.
//! mac address as appears over the air (OUI first)
//!
//!
//*****************************************************************************
extern unsigned char nvmem_set_mac_address(unsigned char *mac);
extern UINT8 nvmem_set_mac_address(UINT8 *mac);
//*****************************************************************************
//
//! nvmem_get_mac_address
//!
//! @param[out] mac mac address
//! @param[out] mac mac address
//!
//! @return on success 0, error otherwise.
//!
//! @brief Read MAC address from EEPROM.
//! @brief Read MAC address from EEPROM.
//! mac address as appears over the air (OUI first)
//!
//!
//*****************************************************************************
extern unsigned char nvmem_get_mac_address(unsigned char *mac);
extern UINT8 nvmem_get_mac_address(UINT8 *mac);
//*****************************************************************************
@@ -170,35 +170,35 @@ extern unsigned char nvmem_get_mac_address(unsigned char *mac);
//!
//! @param ulFileId nvmem file id:\n
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
//! @param spLength number of bytes to write
//! @param spLength number of bytes to write
//! @param spData SP data to write
//!
//! @return on success 0, error otherwise.
//!
//! @brief program a patch to a specific file ID.
//! @brief program a patch to a specific file ID.
//! The SP data is assumed to be organized in 2-dimensional.
//! Each line is SP_PORTION_SIZE bytes long. Actual programming is
//! Each line is SP_PORTION_SIZE bytes long. Actual programming is
//! applied in SP_PORTION_SIZE bytes portions.
//!
//!
//*****************************************************************************
extern unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData);
extern UINT8 nvmem_write_patch(UINT32 ulFileId, UINT32 spLength, const UINT8 *spData);
//*****************************************************************************
//
//! nvmem_read_sp_version
//!
//! @param[out] patchVer first number indicates package ID and the second
//! number indicates package build number
//! @param[out] patchVer first number indicates package ID and the second
//! number indicates package build number
//!
//! @return on success 0, error otherwise.
//!
//! @brief Read patch version. read package version (WiFi FW patch,
//! @brief Read patch version. read package version (WiFi FW patch,
//! driver-supplicant-NS patch, bootloader patch)
//!
//!
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern unsigned char nvmem_read_sp_version(unsigned char* patchVer);
#ifndef CC3000_TINY_DRIVER
extern UINT8 nvmem_read_sp_version(UINT8* patchVer);
#endif
//*****************************************************************************
@@ -209,21 +209,21 @@ extern unsigned char nvmem_read_sp_version(unsigned char* patchVer);
//! * NVMEM_AES128_KEY_FILEID: 12
//! * NVMEM_SHARED_MEM_FILEID: 13
//! * and fileIDs 14 and 15
//! @param ulNewLen entry ulLength
//! @param ulNewLen entry ulLength
//!
//! @return on success 0, error otherwise.
//!
//! @brief Create new file entry and allocate space on the NVMEM.
//! @brief Create new file entry and allocate space on the NVMEM.
//! Applies only to user files.
//! Modify the size of file.
//! If the entry is unallocated - allocate it to size
//! If the entry is unallocated - allocate it to size
//! ulNewLen (marked invalid).
//! If it is allocated then deallocate it first.
//! To just mark the file as invalid without resizing -
//! To just mark the file as invalid without resizing -
//! set ulNewLen=0.
//!
//!
//*****************************************************************************
extern signed long nvmem_create_entry(unsigned long file_id, unsigned long newlen);
extern INT32 nvmem_create_entry(UINT32 file_id, UINT32 newlen);
//*****************************************************************************
@@ -245,4 +245,4 @@ extern signed long nvmem_create_entry(unsigned long file_id, unsigned long newle
}
#endif // __cplusplus
#endif // __NVRAM_H__
#endif // __CC3000_NVRAM_H__

View File

@@ -0,0 +1,11 @@
#ifndef __CC3000_PATCH_PROG_H__
#define __CC3000_PATCH_PROG_H__
extern unsigned short fw_length;
extern const unsigned char fw_patch[];
extern unsigned short drv_length;
extern const unsigned char wlan_drv_patch[];
extern const unsigned char cRMdefaultParams[128];
void patch_prog_start();
#endif //__CC3000_PATCH_PROG_H__

View File

@@ -12,28 +12,28 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __SECURITY__
#define __SECURITY__
#ifndef __CC3000_SECURITY__
#define __CC3000_SECURITY__
#include "nvmem.h"
@@ -64,12 +64,12 @@ extern "C" {
//!
//! @brief AES128 encryption:
//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
//! is computed. The AES implementation is in mode ECB (Electronic
//! Code Book).
//!
//! is computed. The AES implementation is in mode ECB (Electronic
//! Code Book).
//!
//!
//*****************************************************************************
extern void aes_encrypt(unsigned char *state, unsigned char *key);
extern void aes_encrypt(UINT8 *state, UINT8 *key);
//*****************************************************************************
//
@@ -82,12 +82,12 @@ extern void aes_encrypt(unsigned char *state, unsigned char *key);
//!
//! @brief AES128 decryption:
//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
//! is computed The AES implementation is in mode ECB
//! is computed The AES implementation is in mode ECB
//! (Electronic Code Book).
//!
//!
//!
//*****************************************************************************
extern void aes_decrypt(unsigned char *state, unsigned char *key);
extern void aes_decrypt(UINT8 *state, UINT8 *key);
//*****************************************************************************
@@ -100,11 +100,11 @@ extern void aes_decrypt(unsigned char *state, unsigned char *key);
//!
//! @brief Reads AES128 key from EEPROM
//! Reads the AES128 key from fileID #12 in EEPROM
//! returns an error if the key does not exist.
//!
//! returns an error if the key does not exist.
//!
//!
//*****************************************************************************
extern signed long aes_read_key(unsigned char *key);
extern INT32 aes_read_key(UINT8 *key);
//*****************************************************************************
//
@@ -116,18 +116,13 @@ extern signed long aes_read_key(unsigned char *key);
//!
//! @brief writes AES128 key from EEPROM
//! Writes the AES128 key to fileID #12 in EEPROM
//!
//!
//!
//*****************************************************************************
extern signed long aes_write_key(unsigned char *key);
extern INT32 aes_write_key(UINT8 *key);
#endif //CC3000_UNENCRYPTED_SMART_CONFIG
//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@@ -12,29 +12,30 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __SOCKET_H__
#define __SOCKET_H__
#ifndef __CC3000_SOCKET_H__
#define __CC3000_SOCKET_H__
#include "cc3000_common.h"
//*****************************************************************************
//
@@ -83,7 +84,7 @@ extern "C" {
//----------- Socket retunr codes -----------
#define SOC_ERROR (-1) // error
#define SOC_ERROR (-1) // error
#define SOC_IN_PROGRESS (-2) // socket in progress
//----------- Socket Options -----------
@@ -91,7 +92,7 @@ extern "C" {
#define SOCKOPT_RECV_NONBLOCK 0 // recv non block mode, set SOCK_ON or SOCK_OFF (default block mode)
#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout
#define SOCKOPT_ACCEPT_NONBLOCK 2 // accept non block mode, set SOCK_ON or SOCK_OFF (default block mode)
#define SOCK_ON 0 // socket non-blocking mode is enabled
#define SOCK_ON 0 // socket non-blocking mode is enabled
#define SOCK_OFF 1 // socket blocking mode is enabled
#define MAX_PACKET_SIZE 1500
@@ -99,51 +100,44 @@ extern "C" {
#define IOCTL_SOCKET_EVENTMASK
#ifdef ENOBUFS
#undef ENOBUFS
#endif
#define ENOBUFS 55 // No buffer space available
#define __FD_SETSIZE 32
#define ASIC_ADDR_LEN 8
#define NO_QUERY_RECIVED -3
typedef struct _in_addr_t
{
unsigned long s_addr; // load with inet_aton()
UINT32 s_addr; // load with inet_aton()
} in_addr;
typedef struct _sockaddr_t
{
unsigned short int sa_family;
unsigned char sa_data[14];
UINT16 sa_family;
UINT8 sa_data[14];
} sockaddr;
typedef struct _sockaddr_in_t
{
short sin_family; // e.g. AF_INET
unsigned short sin_port; // e.g. htons(3490)
INT16 sin_family; // e.g. AF_INET
UINT16 sin_port; // e.g. htons(3490)
in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
CHAR sin_zero[8]; // zero this if you want to
} sockaddr_in;
typedef unsigned long socklen_t;
typedef UINT32 socklen_t;
// The fd_set member is required to be an array of longs.
typedef long int __fd_mask;
// The fd_set member is required to be an array of INT32s.
typedef INT32 __fd_mask;
// It's easier to assume 8-bit bytes than to get CHAR_BIT.
#define __NFDBITS (8 * sizeof (__fd_mask))
#define __FDELT(d) ((d) / __NFDBITS)
#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
#ifdef fd_set
#undef fd_set // for compatibility with newlib, which defines fd_set
#endif
// fd_set for select and pselect.
typedef struct
{
@@ -155,7 +149,7 @@ typedef struct
// the array isn't too big.
#define __FD_ZERO(set) \
do { \
unsigned int __i; \
UINT16 __i; \
fd_set *__arr = (set); \
for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
__FDS_BITS (__arr)[__i] = 0; \
@@ -165,46 +159,34 @@ typedef struct
#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
// Access macros for 'fd_set'.
#ifdef FD_SET
#undef FD_SET
#endif
#ifdef FD_CLR
#undef FD_CLR
#endif
#ifdef FD_ISSET
#undef FD_ISSET
#endif
#ifdef FD_ZERO
#undef FD_ZERO
#endif
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
//Use in case of Big Endian only
#define htonl(A) ((((unsigned long)(A) & 0xff000000) >> 24) | \
(((unsigned long)(A) & 0x00ff0000) >> 8) | \
(((unsigned long)(A) & 0x0000ff00) << 8) | \
(((unsigned long)(A) & 0x000000ff) << 24))
#define htonl(A) ((((UINT32)(A) & 0xff000000) >> 24) | \
(((UINT32)(A) & 0x00ff0000) >> 8) | \
(((UINT32)(A) & 0x0000ff00) << 8) | \
(((UINT32)(A) & 0x000000ff) << 24))
#define ntohl htonl
//Use in case of Big Endian only
#define htons(A) ((((unsigned long)(A) & 0xff00) >> 8) | \
(((unsigned long)(A) & 0x00ff) << 8))
#define htons(A) ((((UINT32)(A) & 0xff00) >> 8) | \
(((UINT32)(A) & 0x00ff) << 8))
#define ntohs htons
// mDNS port - 5353 mDNS multicast address - 224.0.0.251
// mDNS port - 5353 mDNS multicast address - 224.0.0.251
#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \
sockaddr.sa_data[1] = 0xe9; \
sockaddr.sa_data[2] = 0xe0; \
sockaddr.sa_data[3] = 0x0; \
sockaddr.sa_data[4] = 0x0; \
sockaddr.sa_data[5] = 0xfb;
sockaddr.sa_data[5] = 0xfb;
//*****************************************************************************
@@ -217,24 +199,24 @@ typedef struct
//
//! socket
//!
//! @param domain selects the protocol family which will be used for
//! @param domain selects the protocol family which will be used for
//! communication. On this version only AF_INET is supported
//! @param type specifies the communication semantics. On this version
//! @param type specifies the communication semantics. On this version
//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
//! @param protocol specifies a particular protocol to be used with the
//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
//! @param protocol specifies a particular protocol to be used with the
//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
//! supported.
//!
//! @return On success, socket handle that is used for consequent socket
//! @return On success, socket handle that is used for consequent socket
//! operations. On error, -1 is returned.
//!
//! @brief create an endpoint for communication
//! The socket function creates a socket that is bound to a specific
//! transport service provider. This function is called by the
//! The socket function creates a socket that is bound to a specific
//! transport service provider. This function is called by the
//! application layer to obtain a socket handle.
//
//*****************************************************************************
extern int socket(long domain, long type, long protocol);
extern INT16 CC3000_EXPORT(socket)(INT32 domain, INT32 type, INT32 protocol);
//*****************************************************************************
//
@@ -247,21 +229,21 @@ extern int socket(long domain, long type, long protocol);
//! @brief The socket function closes a created socket.
//
//*****************************************************************************
extern long closesocket(long sd);
extern INT32 CC3000_EXPORT(closesocket)(INT32 sd);
//*****************************************************************************
//
//! accept
//!
//! @param[in] sd socket descriptor (handle)
//! @param[in] sd socket descriptor (handle)
//! @param[out] addr the argument addr is a pointer to a sockaddr structure
//! This structure is filled in with the address of the
//! peer socket, as known to the communications layer.
//! determined. The exact format of the address returned
//! addr is by the socket's address sockaddr.
//! This structure is filled in with the address of the
//! peer socket, as known to the communications layer.
//! determined. The exact format of the address returned
//! addr is by the socket's address sockaddr.
//! On this version only AF_INET is supported.
//! This argument returns in network order.
//! @param[out] addrlen the addrlen argument is a value-result argument:
//! @param[out] addrlen the addrlen argument is a value-result argument:
//! it should initially contain the size of the structure
//! pointed to by addr.
//!
@@ -273,34 +255,34 @@ extern long closesocket(long sd);
//! - On failure, SOC_ERROR (-1)
//!
//! @brief accept a connection on a socket:
//! This function is used with connection-based socket types
//! (SOCK_STREAM). It extracts the first connection request on the
//! This function is used with connection-based socket types
//! (SOCK_STREAM). It extracts the first connection request on the
//! queue of pending connections, creates a new connected socket, and
//! returns a new file descriptor referring to that socket.
//! The newly created socket is not in the listening state.
//! The original socket sd is unaffected by this call.
//! The newly created socket is not in the listening state.
//! The original socket sd is unaffected by this call.
//! The argument sd is a socket that has been created with socket(),
//! bound to a local address with bind(), and is listening for
//! connections after a listen(). The argument addr is a pointer
//! to a sockaddr structure. This structure is filled in with the
//! bound to a local address with bind(), and is listening for
//! connections after a listen(). The argument addr is a pointer
//! to a sockaddr structure. This structure is filled in with the
//! address of the peer socket, as known to the communications layer.
//! The exact format of the address returned addr is determined by the
//! The exact format of the address returned addr is determined by the
//! socket's address family. The addrlen argument is a value-result
//! argument: it should initially contain the size of the structure
//! pointed to by addr, on return it will contain the actual
//! pointed to by addr, on return it will contain the actual
//! length (in bytes) of the address returned.
//!
//! @sa socket ; bind ; listen
//
//*****************************************************************************
extern long accept(long sd, sockaddr *addr, socklen_t *addrlen);
extern INT32 CC3000_EXPORT(accept)(INT32 sd, sockaddr *addr, socklen_t *addrlen);
//*****************************************************************************
//
//! bind
//!
//! @param[in] sd socket descriptor (handle)
//! @param[out] addr specifies the destination address. On this version
//! @param[in] sd socket descriptor (handle)
//! @param[out] addr specifies the destination address. On this version
//! only AF_INET is supported.
//! @param[out] addrlen contains the size of the structure pointed to by addr.
//!
@@ -308,8 +290,8 @@ extern long accept(long sd, sockaddr *addr, socklen_t *addrlen);
//!
//! @brief assign a name to a socket
//! This function gives the socket the local address addr.
//! addr is addrlen bytes long. Traditionally, this is called when a
//! socket is created with socket, it exists in a name space (address
//! addr is addrlen bytes long. Traditionally, this is called when a
//! socket is created with socket, it exists in a name space (address
//! family) but has no name assigned.
//! It is necessary to assign a local address before a SOCK_STREAM
//! socket may receive connections.
@@ -317,13 +299,13 @@ extern long accept(long sd, sockaddr *addr, socklen_t *addrlen);
//! @sa socket ; accept ; listen
//
//*****************************************************************************
extern long bind(long sd, const sockaddr *addr, long addrlen);
extern INT32 CC3000_EXPORT(bind)(INT32 sd, const sockaddr *addr, INT32 addrlen);
//*****************************************************************************
//
//! listen
//!
//! @param[in] sd socket descriptor (handle)
//! @param[in] sd socket descriptor (handle)
//! @param[in] backlog specifies the listen queue depth. On this version
//! backlog is not supported.
//! @return On success, zero is returned. On error, -1 is returned.
@@ -334,35 +316,35 @@ extern long bind(long sd, const sockaddr *addr, long addrlen);
//! and then the connections are accepted with accept.
//! The listen() call applies only to sockets of type SOCK_STREAM
//! The backlog parameter defines the maximum length the queue of
//! pending connections may grow to.
//! pending connections may grow to.
//!
//! @sa socket ; accept ; bind
//!
//! @note On this version, backlog is not supported
//
//*****************************************************************************
extern long listen(long sd, long backlog);
extern INT32 CC3000_EXPORT(listen)(INT32 sd, INT32 backlog);
//*****************************************************************************
//
//! gethostbyname
//!
//! @param[in] hostname host name
//! @param[in] usNameLen name length
//! @param[out] out_ip_addr This parameter is filled in with host IP address.
//! In case that host name is not resolved,
//! out_ip_addr is zero.
//! @param[in] hostname host name
//! @param[in] usNameLen name length
//! @param[out] out_ip_addr This parameter is filled in with host IP address.
//! In case that host name is not resolved,
//! out_ip_addr is zero.
//! @return On success, positive is returned. On error, negative is returned
//!
//! @brief Get host IP by name. Obtain the IP Address of machine on network,
//! @brief Get host IP by name. Obtain the IP Address of machine on network,
//! by its name.
//!
//! @note On this version, only blocking mode is supported. Also note that
//! the function requires DNS server to be configured prior to its usage.
//
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern int gethostbyname(const char* hostname, unsigned short usNameLen, unsigned long* out_ip_addr);
#ifndef CC3000_TINY_DRIVER
extern INT16 CC3000_EXPORT(gethostbyname)(CHAR * hostname, UINT16 usNameLen, UINT32* out_ip_addr);
#endif
@@ -370,43 +352,43 @@ extern int gethostbyname(const char* hostname, unsigned short usNameLen, unsigne
//
//! connect
//!
//! @param[in] sd socket descriptor (handle)
//! @param[in] sd socket descriptor (handle)
//! @param[in] addr specifies the destination addr. On this version
//! only AF_INET is supported.
//! @param[out] addrlen contains the size of the structure pointed to by addr
//! @param[out] addrlen contains the size of the structure pointed to by addr
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief initiate a connection on a socket
//! Function connects the socket referred to by the socket descriptor
//! sd, to the address specified by addr. The addrlen argument
//! specifies the size of addr. The format of the address in addr is
//! determined by the address space of the socket. If it is of type
//! SOCK_DGRAM, this call specifies the peer with which the socket is
//! @brief initiate a connection on a socket
//! Function connects the socket referred to by the socket descriptor
//! sd, to the address specified by addr. The addrlen argument
//! specifies the size of addr. The format of the address in addr is
//! determined by the address space of the socket. If it is of type
//! SOCK_DGRAM, this call specifies the peer with which the socket is
//! to be associated; this address is that to which datagrams are to be
//! sent, and the only address from which datagrams are to be received.
//! If the socket is of type SOCK_STREAM, this call attempts to make a
//! connection to another socket. The other socket is specified by
//! sent, and the only address from which datagrams are to be received.
//! If the socket is of type SOCK_STREAM, this call attempts to make a
//! connection to another socket. The other socket is specified by
//! address, which is an address in the communications space of the
//! socket. Note that the function implements only blocking behavior
//! thus the caller will be waiting either for the connection
//! socket. Note that the function implements only blocking behavior
//! thus the caller will be waiting either for the connection
//! establishment or for the connection establishment failure.
//!
//! @sa socket
//
//*****************************************************************************
extern long connect(long sd, const sockaddr *addr, long addrlen);
extern INT32 CC3000_EXPORT(connect)(INT32 sd, const sockaddr *addr, INT32 addrlen);
//*****************************************************************************
//
//! select
//!
//! @param[in] nfds the highest-numbered file descriptor in any of the
//! three sets, plus 1.
//! three sets, plus 1.
//! @param[out] writesds socket descriptors list for write monitoring
//! @param[out] readsds socket descriptors list for read monitoring
//! @param[out] readsds socket descriptors list for read monitoring
//! @param[out] exceptsds socket descriptors list for exception monitoring
//! @param[in] timeout is an upper bound on the amount of time elapsed
//! before select() returns. Null means infinity
//! before select() returns. Null means infinity
//! timeout. The minimum timeout is 5 milliseconds,
//! less than 5 milliseconds will be set
//! automatically to 5 milliseconds.
@@ -418,14 +400,14 @@ extern long connect(long sd, const sockaddr *addr, long addrlen);
//! On error, -1 is returned.
//! *readsds - return the sockets on which Read request will
//! return without delay with valid data.
//! *writesds - return the sockets on which Write request
//! *writesds - return the sockets on which Write request
//! will return without delay.
//! *exceptsds - return the sockets which closed recently.
//!
//! @brief Monitor socket activity
//! @brief Monitor socket activity
//! Select allow a program to monitor multiple file descriptors,
//! waiting until one or more of the file descriptors become
//! "ready" for some class of I/O operation
//! waiting until one or more of the file descriptors become
//! "ready" for some class of I/O operation
//!
//! @Note If the timeout value set to less than 5ms it will automatically set
//! to 5ms to prevent overload of the system
@@ -433,7 +415,7 @@ extern long connect(long sd, const sockaddr *addr, long addrlen);
//! @sa socket
//
//*****************************************************************************
extern int select(long nfds, fd_set *readsds, fd_set *writesds,
extern INT16 CC3000_EXPORT(select)(INT32 nfds, fd_set *readsds, fd_set *writesds,
fd_set *exceptsds, struct timeval *timeout);
//*****************************************************************************
@@ -451,39 +433,39 @@ extern int select(long nfds, fd_set *readsds, fd_set *writesds,
//! This function manipulate the options associated with a socket.
//! Options may exist at multiple protocol levels; they are always
//! present at the uppermost socket level.
//! When manipulating socket options the level at which the option
//! resides and the name of the option must be specified.
//! To manipulate options at the socket level, level is specified as
//! SOL_SOCKET. To manipulate options at any other level the protocol
//! number of the appropriate protocol controlling the option is
//! supplied. For example, to indicate that an option is to be
//! interpreted by the TCP protocol, level should be set to the
//! protocol number of TCP;
//! The parameters optval and optlen are used to access optval -
//! When manipulating socket options the level at which the option
//! resides and the name of the option must be specified.
//! To manipulate options at the socket level, level is specified as
//! SOL_SOCKET. To manipulate options at any other level the protocol
//! number of the appropriate protocol controlling the option is
//! supplied. For example, to indicate that an option is to be
//! interpreted by the TCP protocol, level should be set to the
//! protocol number of TCP;
//! The parameters optval and optlen are used to access optval -
//! use for setsockopt(). For getsockopt() they identify a buffer
//! in which the value for the requested option(s) are to
//! be returned. For getsockopt(), optlen is a value-result
//! parameter, initially containing the size of the buffer
//! pointed to by option_value, and modified on return to
//! indicate the actual size of the value returned. If no option
//! in which the value for the requested option(s) are to
//! be returned. For getsockopt(), optlen is a value-result
//! parameter, initially containing the size of the buffer
//! pointed to by option_value, and modified on return to
//! indicate the actual size of the value returned. If no option
//! value is to be supplied or returned, option_value may be NULL.
//!
//! @Note On this version the following two socket options are enabled:
//! The only protocol level supported in this version
//! is SOL_SOCKET (level).
//! 1. SOCKOPT_RECV_TIMEOUT (optname)
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
//! in milliseconds.
//! In that case optval should be pointer to unsigned long.
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
//! In that case optval should be pointer to UINT32.
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
//! or off.
//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
//!
//! @sa getsockopt
//
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern int setsockopt(long sd, long level, long optname, const void *optval,
#ifndef CC3000_TINY_DRIVER
extern INT16 CC3000_EXPORT(setsockopt)(INT32 sd, INT32 level, INT32 optname, const void *optval,
socklen_t optlen);
#endif
//*****************************************************************************
@@ -501,38 +483,38 @@ extern int setsockopt(long sd, long level, long optname, const void *optval,
//! This function manipulate the options associated with a socket.
//! Options may exist at multiple protocol levels; they are always
//! present at the uppermost socket level.
//! When manipulating socket options the level at which the option
//! resides and the name of the option must be specified.
//! To manipulate options at the socket level, level is specified as
//! SOL_SOCKET. To manipulate options at any other level the protocol
//! number of the appropriate protocol controlling the option is
//! supplied. For example, to indicate that an option is to be
//! interpreted by the TCP protocol, level should be set to the
//! protocol number of TCP;
//! The parameters optval and optlen are used to access optval -
//! When manipulating socket options the level at which the option
//! resides and the name of the option must be specified.
//! To manipulate options at the socket level, level is specified as
//! SOL_SOCKET. To manipulate options at any other level the protocol
//! number of the appropriate protocol controlling the option is
//! supplied. For example, to indicate that an option is to be
//! interpreted by the TCP protocol, level should be set to the
//! protocol number of TCP;
//! The parameters optval and optlen are used to access optval -
//! use for setsockopt(). For getsockopt() they identify a buffer
//! in which the value for the requested option(s) are to
//! be returned. For getsockopt(), optlen is a value-result
//! parameter, initially containing the size of the buffer
//! pointed to by option_value, and modified on return to
//! indicate the actual size of the value returned. If no option
//! in which the value for the requested option(s) are to
//! be returned. For getsockopt(), optlen is a value-result
//! parameter, initially containing the size of the buffer
//! pointed to by option_value, and modified on return to
//! indicate the actual size of the value returned. If no option
//! value is to be supplied or returned, option_value may be NULL.
//!
//! @Note On this version the following two socket options are enabled:
//! The only protocol level supported in this version
//! is SOL_SOCKET (level).
//! 1. SOCKOPT_RECV_TIMEOUT (optname)
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
//! in milliseconds.
//! In that case optval should be pointer to unsigned long.
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
//! In that case optval should be pointer to UINT32.
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
//! or off.
//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
//!
//! @sa setsockopt
//
//*****************************************************************************
extern int getsockopt(long sd, long level, long optname, void *optval,
extern INT16 CC3000_EXPORT(getsockopt)(INT32 sd, INT32 level, INT32 optname, void *optval,
socklen_t *optlen);
//*****************************************************************************
@@ -541,9 +523,9 @@ extern int getsockopt(long sd, long level, long optname, void *optval,
//!
//! @param[in] sd socket handle
//! @param[out] buf Points to the buffer where the message should be stored
//! @param[in] len Specifies the length in bytes of the buffer pointed to
//! @param[in] len Specifies the length in bytes of the buffer pointed to
//! by the buffer argument.
//! @param[in] flags Specifies the type of message reception.
//! @param[in] flags Specifies the type of message reception.
//! On this version, this parameter is not supported.
//!
//! @return Return the number of bytes received, or -1 if an error
@@ -556,7 +538,7 @@ extern int getsockopt(long sd, long level, long optname, void *optval,
//! @Note On this version, only blocking mode is supported.
//
//*****************************************************************************
extern int recv(long sd, void *buf, long len, long flags);
extern INT16 CC3000_EXPORT(recv)(INT32 sd, void *buf, INT32 len, INT32 flags);
//*****************************************************************************
//
@@ -564,9 +546,9 @@ extern int recv(long sd, void *buf, long len, long flags);
//!
//! @param[in] sd socket handle
//! @param[out] buf Points to the buffer where the message should be stored
//! @param[in] len Specifies the length in bytes of the buffer pointed to
//! @param[in] len Specifies the length in bytes of the buffer pointed to
//! by the buffer argument.
//! @param[in] flags Specifies the type of message reception.
//! @param[in] flags Specifies the type of message reception.
//! On this version, this parameter is not supported.
//! @param[in] from pointer to an address structure indicating the source
//! address: sockaddr. On this version only AF_INET is
@@ -586,7 +568,7 @@ extern int recv(long sd, void *buf, long len, long flags);
//! @Note On this version, only blocking mode is supported.
//
//*****************************************************************************
extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
extern INT16 CC3000_EXPORT(recvfrom)(INT32 sd, void *buf, INT32 len, INT32 flags, sockaddr *from,
socklen_t *fromlen);
//*****************************************************************************
@@ -602,7 +584,7 @@ extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
//! error occurred
//!
//! @brief Write data to TCP socket
//! This function is used to transmit a message to another
//! This function is used to transmit a message to another
//! socket.
//!
//! @Note On this version, only blocking mode is supported.
@@ -611,7 +593,7 @@ extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
//
//*****************************************************************************
extern int send(long sd, const void *buf, long len, long flags);
extern INT16 CC3000_EXPORT(send)(INT32 sd, const void *buf, INT32 len, INT32 flags);
//*****************************************************************************
//
@@ -630,7 +612,7 @@ extern int send(long sd, const void *buf, long len, long flags);
//! error occurred
//!
//! @brief Write data to TCP socket
//! This function is used to transmit a message to another
//! This function is used to transmit a message to another
//! socket.
//!
//! @Note On this version, only blocking mode is supported.
@@ -639,7 +621,7 @@ extern int send(long sd, const void *buf, long len, long flags);
//
//*****************************************************************************
extern int sendto(long sd, const void *buf, long len, long flags,
extern INT16 CC3000_EXPORT(sendto)(INT32 sd, const void *buf, INT32 len, INT32 flags,
const sockaddr *to, socklen_t tolen);
//*****************************************************************************
@@ -649,16 +631,30 @@ extern int sendto(long sd, const void *buf, long len, long flags,
//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
//! @param[in] deviceServiceName Service name as part of the published
//! canonical domain name
//! @param[in] deviceServiceNameLength Length of the service name
//! @param[in] deviceServiceNameLength Length of the service name - up to 32 chars
//!
//!
//!
//! @return On success, zero is returned, return SOC_ERROR if socket was not
//! @return On success, zero is returned, return SOC_ERROR if socket was not
//! opened successfully, or if an error occurred.
//!
//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
//
//*****************************************************************************
extern int mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength);
extern INT16 CC3000_EXPORT(mdnsAdvertiser)(UINT16 mdnsEnabled, CHAR * deviceServiceName, UINT16 deviceServiceNameLength);
//*****************************************************************************
//
//! getmssvalue
//!
//! @param[in] sd socket descriptor
//!
//! @return On success, returns the MSS value of a TCP connection
//!
//! @brief Returns the MSS value of a TCP connection according to the socket descriptor
//
//*****************************************************************************
extern UINT16 CC3000_EXPORT(getmssvalue) (INT32 sd);
//*****************************************************************************
//

View File

@@ -12,28 +12,28 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __WLAN_H__
#define __WLAN_H__
#ifndef __CC3000_WLAN_H__
#define __CC3000_WLAN_H__
#include "cc3000_common.h"
@@ -63,41 +63,41 @@ extern "C" {
//
//! wlan_init
//!
//! @param sWlanCB Asynchronous events callback.
//! @param sWlanCB Asynchronous events callback.
//! 0 no event call back.
//! -call back parameters:
//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event,
//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event,
//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done,
//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report,
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR
//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report,
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR
//! HCI_EVNT_WLAN_KEEPALIVE keepalive.
//! 2) data: pointer to extra data that received by the event
//! (NULL no data).
//! 3) length: data length.
//! -Events with extra data:
//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask,
//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask,
//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes
//! for DNS server.
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent,
//! 4 bytes Packets received, 4 bytes Min round time,
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent,
//! 4 bytes Packets received, 4 bytes Min round time,
//! 4 bytes Max round time and 4 bytes for Avg round time.
//!
//! @param sFWPatches 0 no patch or pointer to FW patches
//! @param sFWPatches 0 no patch or pointer to FW patches
//! @param sDriverPatches 0 no patch or pointer to driver patches
//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches
//! @param sReadWlanInterruptPin init callback. the callback read wlan
//! @param sReadWlanInterruptPin init callback. the callback read wlan
//! interrupt status.
//! @param sWlanInterruptEnable init callback. the callback enable wlan
//! @param sWlanInterruptEnable init callback. the callback enable wlan
//! interrupt.
//! @param sWlanInterruptDisable init callback. the callback disable wlan
//! interrupt.
//! @param sWriteWlanPin init callback. the callback write value
//! to device pin.
//! @param sWriteWlanPin init callback. the callback write value
//! to device pin.
//!
//! @return none
//!
//! @sa wlan_set_event_mask , wlan_start , wlan_stop
//! @sa wlan_set_event_mask , wlan_start , wlan_stop
//!
//! @brief Initialize wlan driver
//!
@@ -120,28 +120,28 @@ extern void wlan_init( tWlanCB sWlanCB,
//! wlan_start
//!
//! @param usPatchesAvailableAtHost - flag to indicate if patches available
//! from host or from EEPROM. Due to the
//! from host or from EEPROM. Due to the
//! fact the patches are burn to the EEPROM
//! using the patch programmer utility, the
//! using the patch programmer utility, the
//! patches will be available from the EEPROM
//! and not from the host.
//!
//! @return none
//!
//! @brief Start WLAN device. This function asserts the enable pin of
//! @brief Start WLAN device. This function asserts the enable pin of
//! the device (WLAN_EN), starting the HW initialization process.
//! The function blocked until device Initialization is completed.
//! Function also configure patches (FW, driver or bootloader)
//! Function also configure patches (FW, driver or bootloader)
//! and calls appropriate device callbacks.
//!
//! @Note Prior calling the function wlan_init shall be called.
//! @Warning This function must be called after wlan_init and before any
//! @Warning This function must be called after wlan_init and before any
//! other wlan API
//! @sa wlan_init , wlan_stop
//!
//
//*****************************************************************************
extern void wlan_start(unsigned short usPatchesAvailableAtHost);
extern int wlan_start(UINT16 usPatchesAvailableAtHost);
//*****************************************************************************
//
@@ -163,23 +163,23 @@ extern void wlan_stop(void);
//! wlan_connect
//!
//! @param sec_type security options:
//! WLAN_SEC_UNSEC,
//! WLAN_SEC_UNSEC,
//! WLAN_SEC_WEP (ASCII support only),
//! WLAN_SEC_WPA or WLAN_SEC_WPA2
//! @param ssid up to 32 bytes and is ASCII SSID of the AP
//! @param ssid_len length of the SSID
//! @param bssid 6 bytes specified the AP bssid
//! @param key up to 32 bytes specified the AP security key
//! @param key_len key length
//! @param key_len key length
//!
//! @return On success, zero is returned. On error, negative is returned.
//! @return On success, zero is returned. On error, negative is returned.
//! Note that even though a zero is returned on success to trigger
//! connection operation, it does not mean that CCC3000 is already
//! connected. An asynchronous "Connected" event is generated when
//! connected. An asynchronous "Connected" event is generated when
//! actual association process finishes and CC3000 is connected to
//! the AP. If DHCP is set, An asynchronous "DHCP" event is
//! the AP. If DHCP is set, An asynchronous "DHCP" event is
//! generated when DHCP process is finish.
//!
//!
//!
//! @brief Connect to AP
//! @warning Please Note that when connection to AP configured with security
@@ -189,10 +189,10 @@ extern void wlan_stop(void);
//
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
extern long wlan_connect(unsigned long ulSecType, const char *ssid, long ssid_len,
unsigned char *bssid, unsigned char *key, long key_len);
extern INT32 wlan_connect(UINT32 ulSecType, CHAR *ssid, INT32 ssid_len,
UINT8 *bssid, UINT8 *key, INT32 key_len);
#else
extern long wlan_connect(const char *ssid, long ssid_len);
extern INT32 wlan_connect(CHAR *ssid, INT32 ssid_len);
#endif
@@ -200,15 +200,15 @@ extern long wlan_connect(const char *ssid, long ssid_len);
//
//! wlan_disconnect
//!
//! @return 0 disconnected done, other CC3000 already disconnected
//! @return 0 disconnected done, other CC3000 already disconnected
//!
//! @brief Disconnect connection from AP.
//! @brief Disconnect connection from AP.
//!
//! @sa wlan_connect
//
//*****************************************************************************
extern long wlan_disconnect(void);
extern INT32 wlan_disconnect(void);
//*****************************************************************************
//
@@ -221,32 +221,33 @@ extern long wlan_disconnect(void);
//! @param ulPriority ulPriority profile priority. Lowest priority:0.
//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security
//! @param ulGroupCipher_TxKeyIndex key index
//! @param ulKeyMgmt KEY management
//! @param ulKeyMgmt KEY management
//! @param ucPf_OrKey security key
//! @param ulPassPhraseLen security key length for WPA\WPA2
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, index (1-7) of the stored profile is returned.
//! On error, -1 is returned.
//!
//! @brief When auto start is enabled, the device connects to
//! station from the profiles table. Up to 7 profiles are supported.
//! If several profiles configured the device choose the highest
//! priority profile, within each priority group, device will choose
//! profile based on security policy, signal strength, etc
//! station from the profiles table. Up to 7 profiles are supported.
//! If several profiles configured the device choose the highest
//! priority profile, within each priority group, device will choose
//! profile based on security policy, signal strength, etc
//! parameters. All the profiles are stored in CC3000 NVMEM.
//!
//! @sa wlan_ioctl_del_profile
//! @sa wlan_ioctl_del_profile
//
//*****************************************************************************
extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid,
unsigned long ulSsidLen,
unsigned char *ucBssid,
unsigned long ulPriority,
unsigned long ulPairwiseCipher_Or_Key,
unsigned long ulGroupCipher_TxKeyLen,
unsigned long ulKeyMgmt,
unsigned char* ucPf_OrKey,
unsigned long ulPassPhraseLen);
extern INT32 wlan_add_profile(UINT32 ulSecType, UINT8* ucSsid,
UINT32 ulSsidLen,
UINT8 *ucBssid,
UINT32 ulPriority,
UINT32 ulPairwiseCipher_Or_Key,
UINT32 ulGroupCipher_TxKeyLen,
UINT32 ulKeyMgmt,
UINT8* ucPf_OrKey,
UINT32 ulPassPhraseLen);
@@ -256,16 +257,16 @@ extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid,
//!
//! @param index number of profile to delete
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief Delete WLAN profile
//! @brief Delete WLAN profile
//!
//! @Note In order to delete all stored profile, set index to 255.
//!
//! @sa wlan_add_profile
//! @sa wlan_add_profile
//
//*****************************************************************************
extern long wlan_ioctl_del_profile(unsigned long ulIndex);
extern INT32 wlan_ioctl_del_profile(UINT32 ulIndex);
//*****************************************************************************
//
@@ -282,64 +283,64 @@ extern long wlan_ioctl_del_profile(unsigned long ulIndex);
//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission
//! Saved: no.
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief Mask event according to bit mask. In case that event is
//! masked (1), the device will not send the masked event to host.
//! @brief Mask event according to bit mask. In case that event is
//! masked (1), the device will not send the masked event to host.
//
//*****************************************************************************
extern long wlan_set_event_mask(unsigned long ulMask);
extern INT32 wlan_set_event_mask(UINT32 ulMask);
//*****************************************************************************
//
//! wlan_ioctl_statusget
//!
//! @param none
//! @param none
//!
//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING,
//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED
//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING,
//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED
//!
//! @brief get wlan status: disconnected, scanning, connecting or connected
//
//*****************************************************************************
extern long wlan_ioctl_statusget(void);
extern INT32 wlan_ioctl_statusget(void);
//*****************************************************************************
//
//! wlan_ioctl_set_connection_policy
//!
//! @param should_connect_to_open_ap enable(1), disable(0) connect to any
//! available AP. This parameter corresponds to the configuration of
//! @param should_connect_to_open_ap enable(1), disable(0) connect to any
//! available AP. This parameter corresponds to the configuration of
//! item # 3 in the brief description.
//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries
//! to connect to the last connected AP. This parameter corresponds
//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries
//! to connect to the last connected AP. This parameter corresponds
//! to the configuration of item # 1 in the brief description.
//! @param auto_start enable(1), disable(0) auto connect
//! after reset and periodically reconnect if needed. This
//! @param auto_start enable(1), disable(0) auto connect
//! after reset and periodically reconnect if needed. This
//! configuration configures option 2 in the above description.
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief When auto is enabled, the device tries to connect according
//! @brief When auto is enabled, the device tries to connect according
//! the following policy:
//! 1) If fast connect is enabled and last connection is valid,
//! the device will try to connect to it without the scanning
//! 1) If fast connect is enabled and last connection is valid,
//! the device will try to connect to it without the scanning
//! procedure (fast). The last connection will be marked as
//! invalid, due to adding/removing profile.
//! 2) If profile exists, the device will try to connect it
//! invalid, due to adding/removing profile.
//! 2) If profile exists, the device will try to connect it
//! (Up to seven profiles).
//! 3) If fast and profiles are not found, and open mode is
//! enabled, the device will try to connect to any AP.
//! * Note that the policy settings are stored in the CC3000 NVMEM.
//!
//! @sa wlan_add_profile , wlan_ioctl_del_profile
//! @sa wlan_add_profile , wlan_ioctl_del_profile
//
//*****************************************************************************
extern long wlan_ioctl_set_connection_policy(
unsigned long should_connect_to_open_ap,
unsigned long should_use_fast_connect,
unsigned long ulUseProfiles);
extern INT32 wlan_ioctl_set_connection_policy(
UINT32 should_connect_to_open_ap,
UINT32 should_use_fast_connect,
UINT32 ulUseProfiles);
//*****************************************************************************
//
@@ -348,94 +349,94 @@ extern long wlan_ioctl_set_connection_policy(
//! @param[in] scan_timeout parameter not supported
//! @param[out] ucResults scan result (_wlan_full_scan_results_args_t)
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief Gets entry from scan result table.
//! The scan results are returned one by one, and each entry
//! represents a single AP found in the area. The following is a
//! format of the scan result:
//! The scan results are returned one by one, and each entry
//! represents a single AP found in the area. The following is a
//! format of the scan result:
//! - 4 Bytes: number of networks found
//! - 4 Bytes: The status of the scan: 0 - aged results,
//! 1 - results valid, 2 - no results
//! - 42 bytes: Result entry, where the bytes are arranged as follows:
//!
//!
//! - 1 bit isValid - is result valid or not
//! - 7 bits rssi - RSSI value;
//! - 7 bits rssi - RSSI value;
//! - 2 bits: securityMode - security mode of the AP:
//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2
//! - 6 bits: SSID name length
//! - 2 bytes: the time at which the entry has entered into
//! - 2 bytes: the time at which the entry has entered into
//! scans result table
//! - 32 bytes: SSID name
//! - 6 bytes: BSSID
//! - 6 bytes: BSSID
//!
//! @Note scan_timeout, is not supported on this version.
//!
//! @sa wlan_ioctl_set_scan_params
//! @sa wlan_ioctl_set_scan_params
//
//*****************************************************************************
extern long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
unsigned char *ucResults);
extern INT32 wlan_ioctl_get_scan_results(UINT32 ulScanTimeout,
UINT8 *ucResults);
//*****************************************************************************
//
//! wlan_ioctl_set_scan_params
//!
//! @param uiEnable - start/stop application scan:
//! 1 = start scan with default interval value of 10 min.
//! in order to set a different scan interval value apply the value
//! @param uiEnable - start/stop application scan:
//! 1 = start scan with default interval value of 10 min.
//! in order to set a different scan interval value apply the value
//! in milliseconds. minimum 1 second. 0=stop). Wlan reset
//! (wlan_stop() wlan_start()) is needed when changing scan interval
//! value. Saved: No
//! @param uiMinDwellTime minimum dwell time value to be used for each
//! @param uiMinDwellTime minimum dwell time value to be used for each
//! channel, in milliseconds. Saved: yes
//! Recommended Value: 100 (Default: 20)
//! @param uiMaxDwellTime maximum dwell time value to be used for each
//! channel, in milliseconds. Saved: yes
//! Recommended Value: 100 (Default: 30)
//! @param uiNumOfProbeRequests max probe request between dwell time.
//! @param uiNumOfProbeRequests max probe request between dwell time.
//! Saved: yes. Recommended Value: 5 (Default:2)
//! @param uiChannelMask bitwise, up to 13 channels (0x1fff).
//! @param uiChannelMask bitwise, up to 13 channels (0x1fff).
//! Saved: yes. Default: 0x7ff
//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80)
//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0)
//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205)
//! @param aiIntervalList pointer to array with 16 entries (16 channels)
//! each entry (unsigned long) holds timeout between periodic scan
//! @param aiIntervalList pointer to array with 16 entries (16 channels)
//! each entry (UINT32) holds timeout between periodic scan
//! (connection scan) - in milliseconds. Saved: yes. Default 2000ms.
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief start and stop scan procedure. Set scan parameters.
//! @brief start and stop scan procedure. Set scan parameters.
//!
//! @Note uiDefaultTxPower, is not supported on this version.
//!
//! @sa wlan_ioctl_get_scan_results
//! @sa wlan_ioctl_get_scan_results
//
//*****************************************************************************
extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long
uiMinDwellTime,unsigned long uiMaxDwellTime,
unsigned long uiNumOfProbeRequests,
unsigned long uiChannelMask,
long iRSSIThreshold,unsigned long uiSNRThreshold,
unsigned long uiDefaultTxPower,
unsigned long *aiIntervalList);
extern INT32 wlan_ioctl_set_scan_params(UINT32 uiEnable, UINT32
uiMinDwellTime,UINT32 uiMaxDwellTime,
UINT32 uiNumOfProbeRequests,
UINT32 uiChannelMask,
INT32 iRSSIThreshold,UINT32 uiSNRThreshold,
UINT32 uiDefaultTxPower,
UINT32 *aiIntervalList);
//*****************************************************************************
//
//! wlan_smart_config_start
//!
//! @param algoEncryptedFlag indicates whether the information is encrypted
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief Start to acquire device profile. The device acquire its own
//! @brief Start to acquire device profile. The device acquire its own
//! profile, if profile message is found. The acquired AP information
//! is stored in CC3000 EEPROM only in case AES128 encryption is used.
//! In case AES128 encryption is not used, a profile is created by
//! In case AES128 encryption is not used, a profile is created by
//! CC3000 internally.
//!
//! @Note An asynchronous event - Smart Config Done will be generated as soon
@@ -443,8 +444,8 @@ extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long
//!
//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop
//
//*****************************************************************************
extern long wlan_smart_config_start(unsigned long algoEncryptedFlag);
//*****************************************************************************
extern INT32 wlan_smart_config_start(UINT32 algoEncryptedFlag);
//*****************************************************************************
@@ -453,24 +454,24 @@ extern long wlan_smart_config_start(unsigned long algoEncryptedFlag);
//!
//! @param algoEncryptedFlag indicates whether the information is encrypted
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief Stop the acquire profile procedure
//! @brief Stop the acquire profile procedure
//!
//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix
//
//*****************************************************************************
extern long wlan_smart_config_stop(void);
extern INT32 wlan_smart_config_stop(void);
//*****************************************************************************
//
//! wlan_smart_config_set_prefix
//!
//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config.
//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config.
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief Configure station ssid prefix. The prefix is used internally
//! @brief Configure station ssid prefix. The prefix is used internally
//! in CC3000. It should always be TTT.
//!
//! @Note The prefix is stored in CC3000 NVMEM
@@ -478,23 +479,23 @@ extern long wlan_smart_config_stop(void);
//! @sa wlan_smart_config_start , wlan_smart_config_stop
//
//*****************************************************************************
extern long wlan_smart_config_set_prefix(char* cNewPrefix);
extern INT32 wlan_smart_config_set_prefix(CHAR* cNewPrefix);
//*****************************************************************************
//
//! wlan_smart_config_process
//!
//! @param none
//! @param none
//!
//! @return On success, zero is returned. On error, -1 is returned
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief process the acquired data and store it as a profile. The acquired
//! @brief process the acquired data and store it as a profile. The acquired
//! AP information is stored in CC3000 EEPROM encrypted.
//! The encrypted data is decrypted and stored as a profile.
//! behavior is as defined by connection policy.
//
//*****************************************************************************
extern long wlan_smart_config_process(void);
extern INT32 wlan_smart_config_process(void);
//*****************************************************************************
//
@@ -514,4 +515,4 @@ extern long wlan_smart_config_process(void);
}
#endif // __cplusplus
#endif // __WLAN_H__
#endif // __CC3000_WLAN_H__

View File

@@ -12,23 +12,23 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
@@ -39,14 +39,10 @@
//
//*****************************************************************************
/******************************************************************************
*
* Include files
*
*****************************************************************************/
#include <stdint.h>
#include "mpconfigport.h"
#if MICROPY_HW_ENABLE_CC3K
*
* Include files
*
*****************************************************************************/
#include "cc3000_common.h"
#include "socket.h"
@@ -65,10 +61,9 @@
//! @brief stub function for ASSERT macro
//
//*****************************************************************************
void
__error__(char *pcFilename, unsigned long ulLine)
void __error__(CHAR *pcFilename, UINT32 ulLine)
{
//TODO full up function
//TODO full up function
}
@@ -87,12 +82,12 @@ __error__(char *pcFilename, unsigned long ulLine)
//
//*****************************************************************************
unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32)
UINT8* UINT32_TO_STREAM_f (UINT8 *p, UINT32 u32)
{
*(p)++ = (unsigned char)(u32);
*(p)++ = (unsigned char)((u32) >> 8);
*(p)++ = (unsigned char)((u32) >> 16);
*(p)++ = (unsigned char)((u32) >> 24);
*(p)++ = (UINT8)(u32);
*(p)++ = (UINT8)((u32) >> 8);
*(p)++ = (UINT8)((u32) >> 16);
*(p)++ = (UINT8)((u32) >> 24);
return p;
}
@@ -110,10 +105,10 @@ unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32)
//
//*****************************************************************************
unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16)
UINT8* UINT16_TO_STREAM_f (UINT8 *p, UINT16 u16)
{
*(p)++ = (unsigned char)(u16);
*(p)++ = (unsigned char)((u16) >> 8);
*(p)++ = (UINT8)(u16);
*(p)++ = (UINT8)((u16) >> 8);
return p;
}
@@ -131,10 +126,10 @@ unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16)
//
//*****************************************************************************
unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset)
UINT16 STREAM_TO_UINT16_f(CHAR* p, UINT16 offset)
{
return (unsigned short)((unsigned short)((unsigned short)
(*(p + offset + 1)) << 8) + (unsigned short)(*(p + offset)));
return (UINT16)((UINT16)((UINT16)
(*(p + offset + 1)) << 8) + (UINT16)(*(p + offset)));
}
//*****************************************************************************
@@ -151,12 +146,12 @@ unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset)
//
//*****************************************************************************
unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset)
UINT32 STREAM_TO_UINT32_f(CHAR* p, UINT16 offset)
{
return (unsigned long)((unsigned long)((unsigned long)
(*(p + offset + 3)) << 24) + (unsigned long)((unsigned long)
(*(p + offset + 2)) << 16) + (unsigned long)((unsigned long)
(*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset)));
return (UINT32)((UINT32)((UINT32)
(*(p + offset + 3)) << 24) + (UINT32)((UINT32)
(*(p + offset + 2)) << 16) + (UINT32)((UINT32)
(*(p + offset + 1)) << 8) + (UINT32)(*(p + offset)));
}
@@ -167,5 +162,3 @@ unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset)
//! @}
//
//*****************************************************************************
#endif // MICROPY_HW_ENABLE_CC3K

461
drivers/cc3000/src/ccspi.c Normal file
View File

@@ -0,0 +1,461 @@
/*****************************************************************************
*
* spi.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include <string.h>
#include "stm32f4xx_hal.h"
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include "pin.h"
#include "led.h"
#include "extint.h"
#include "spi.h"
#include "ccspi.h"
#include "evnt_handler.h"
#if 0 // print debugging info
#include <stdio.h>
#define DEBUG_printf(args...) printf(args)
#else // don't print debugging info
#define DEBUG_printf(args...) (void)0
#endif
// these need to be set to valid values before anything in this file will work
STATIC SPI_HandleTypeDef *SPI_HANDLE = NULL;
STATIC const pin_obj_t *PIN_CS = NULL;
STATIC const pin_obj_t *PIN_EN = NULL;
STATIC const pin_obj_t *PIN_IRQ = NULL;
#define CS_LOW() HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_RESET)
#define CS_HIGH() HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET)
#define READ 3
#define WRITE 1
#define HI(value) (((value) & 0xFF00) >> 8)
#define LO(value) ((value) & 0x00FF)
#define SPI_TIMEOUT (1000)
#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5)
/* SPI bus states */
#define eSPI_STATE_POWERUP (0)
#define eSPI_STATE_INITIALIZED (1)
#define eSPI_STATE_IDLE (2)
#define eSPI_STATE_WRITE_IRQ (3)
#define eSPI_STATE_WRITE_FIRST_PORTION (4)
#define eSPI_STATE_WRITE_EOT (5)
#define eSPI_STATE_READ_IRQ (6)
#define eSPI_STATE_READ_FIRST_PORTION (7)
#define eSPI_STATE_READ_EOT (8)
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
// for the purpose of detection of the overrun. The location of the memory where the magic number
// resides shall never be written. In case it is written - the overrun occured and either recevie function
// or send function will stuck forever.
#define CC3000_BUFFER_MAGIC_NUMBER (0xDE)
typedef struct {
gcSpiHandleRx SPIRxHandler;
unsigned short usTxPacketLength;
unsigned short usRxPacketLength;
unsigned long ulSpiState;
unsigned char *pTxPacket;
unsigned char *pRxPacket;
} tSpiInformation;
tSpiInformation sSpiInformation;
char spi_buffer[CC3000_RX_BUFFER_SIZE];
unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
STATIC const mp_obj_fun_builtin_t irq_callback_obj;
void SpiWriteDataSynchronous(unsigned char *data, unsigned short size);
void SpiReadDataSynchronous(unsigned char *data, unsigned short size);
// set the pins to use to communicate with the CC3000
// the arguments must be of type pin_obj_t* and SPI_HandleTypeDef*
void SpiInit(void *spi, const void *pin_cs, const void *pin_en, const void *pin_irq) {
SPI_HANDLE = spi;
PIN_CS = pin_cs;
PIN_EN = pin_en;
PIN_IRQ = pin_irq;
}
void SpiClose(void)
{
if (sSpiInformation.pRxPacket) {
sSpiInformation.pRxPacket = 0;
}
tSLInformation.WlanInterruptDisable();
//HAL_SPI_DeInit(SPI_HANDLE);
}
void SpiOpen(gcSpiHandleRx pfRxHandler)
{
DEBUG_printf("SpiOpen\n");
/* initialize SPI state */
sSpiInformation.ulSpiState = eSPI_STATE_POWERUP;
sSpiInformation.SPIRxHandler = pfRxHandler;
sSpiInformation.usTxPacketLength = 0;
sSpiInformation.pTxPacket = NULL;
sSpiInformation.pRxPacket = (unsigned char *)spi_buffer;
sSpiInformation.usRxPacketLength = 0;
spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
/* SPI configuration */
SPI_HANDLE->Init.Mode = SPI_MODE_MASTER;
SPI_HANDLE->Init.Direction = SPI_DIRECTION_2LINES;
SPI_HANDLE->Init.DataSize = SPI_DATASIZE_8BIT;
SPI_HANDLE->Init.CLKPolarity = SPI_POLARITY_LOW;
SPI_HANDLE->Init.CLKPhase = SPI_PHASE_2EDGE;
SPI_HANDLE->Init.NSS = SPI_NSS_SOFT;
SPI_HANDLE->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
SPI_HANDLE->Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_HANDLE->Init.TIMode = SPI_TIMODE_DISABLED;
SPI_HANDLE->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SPI_HANDLE->Init.CRCPolynomial = 7;
spi_init(SPI_HANDLE, false);
// configure wlan CS and EN pins
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = 0;
GPIO_InitStructure.Pin = PIN_CS->pin_mask;
HAL_GPIO_Init(PIN_CS->gpio, &GPIO_InitStructure);
GPIO_InitStructure.Pin = PIN_EN->pin_mask;
HAL_GPIO_Init(PIN_EN->gpio, &GPIO_InitStructure);
HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET);
HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask, GPIO_PIN_RESET);
/* do a dummy read, this ensures SCLK is low before
actual communications start, it might be required */
CS_LOW();
uint8_t buf[1];
HAL_SPI_Receive(SPI_HANDLE, buf, sizeof(buf), SPI_TIMEOUT);
CS_HIGH();
// register EXTI
extint_register((mp_obj_t)PIN_IRQ, GPIO_MODE_IT_FALLING, GPIO_PULLUP, (mp_obj_t)&irq_callback_obj, true, NULL);
extint_enable(PIN_IRQ->pin);
DEBUG_printf("SpiOpen finished; IRQ.pin=%d IRQ_LINE=%d\n", PIN_IRQ->pin, PIN_IRQ->pin);
}
void SpiPauseSpi(void)
{
extint_disable(PIN_IRQ->pin);
}
void SpiResumeSpi(void)
{
extint_enable(PIN_IRQ->pin);
}
long ReadWlanInterruptPin(void)
{
return HAL_GPIO_ReadPin(PIN_IRQ->gpio, PIN_IRQ->pin_mask);
}
void WriteWlanPin(unsigned char val)
{
HAL_GPIO_WritePin(PIN_EN->gpio, PIN_EN->pin_mask,
(WLAN_ENABLE)? GPIO_PIN_SET:GPIO_PIN_RESET);
}
void __delay_cycles(volatile int x)
{
x *= 6; // for 168 MHz CPU
while (x--);
}
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength)
{
DEBUG_printf("SpiFirstWrite %lu\n", sSpiInformation.ulSpiState);
CS_LOW();
// Assuming we are running on 24 MHz ~50 micro delay is 1200 cycles;
__delay_cycles(1200);
// SPI writes first 4 bytes of data
SpiWriteDataSynchronous(ucBuf, 4);
__delay_cycles(1200);
SpiWriteDataSynchronous(ucBuf + 4, usLength - 4);
// From this point on - operate in a regular way
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
CS_HIGH();
return(0);
}
long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength)
{
DEBUG_printf("SpiWrite %lu\n", sSpiInformation.ulSpiState);
unsigned char ucPad = 0;
// Figure out the total length of the packet in order to figure out if there
// is padding or not
if(!(usLength & 0x0001)) {
ucPad++;
}
pUserBuffer[0] = WRITE;
pUserBuffer[1] = HI(usLength + ucPad);
pUserBuffer[2] = LO(usLength + ucPad);
pUserBuffer[3] = 0;
pUserBuffer[4] = 0;
usLength += (SPI_HEADER_SIZE + ucPad);
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
// for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun
// occurred - and we will stuck here forever!
if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) {
while (1);
}
if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) {
while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED);
}
if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED) {
// This is time for first TX/RX transactions over SPI:
// the IRQ is down - so need to send read buffer size command
SpiFirstWrite(pUserBuffer, usLength);
} else {
//
// We need to prevent here race that can occur in case 2 back to back packets are sent to the
// device, so the state will move to IDLE and once again to not IDLE due to IRQ
//
tSLInformation.WlanInterruptDisable();
while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE);
sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ;
sSpiInformation.pTxPacket = pUserBuffer;
sSpiInformation.usTxPacketLength = usLength;
// Assert the CS line and wait till SSI IRQ line is active and then initialize write operation
CS_LOW();
// Re-enable IRQ - if it was not disabled - this is not a problem...
tSLInformation.WlanInterruptEnable();
// check for a missing interrupt between the CS assertion and enabling back the interrupts
if (tSLInformation.ReadWlanInterruptPin() == 0) {
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
CS_HIGH();
}
}
// Due to the fact that we are currently implementing a blocking situation
// here we will wait till end of transaction
while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState);
return(0);
}
void SpiWriteDataSynchronous(unsigned char *data, unsigned short size)
{
DEBUG_printf("SpiWriteDataSynchronous(data=%p [%x %x %x %x], size=%u)\n", data, data[0], data[1], data[2], data[3], size);
__disable_irq();
if (HAL_SPI_TransmitReceive(SPI_HANDLE, data, data, size, SPI_TIMEOUT) != HAL_OK) {
//BREAK();
}
__enable_irq();
DEBUG_printf(" - rx data = [%x %x %x %x]\n", data[0], data[1], data[2], data[3]);
}
void SpiReadDataSynchronous(unsigned char *data, unsigned short size)
{
memset(data, READ, size);
__disable_irq();
if (HAL_SPI_TransmitReceive(SPI_HANDLE, data, data, size, SPI_TIMEOUT) != HAL_OK) {
//BREAK();
}
__enable_irq();
}
void SpiReadPacket(void)
{
int length;
/* read SPI header */
SpiReadDataSynchronous(sSpiInformation.pRxPacket, SPI_HEADER_SIZE);
/* parse data length */
STREAM_TO_UINT8(sSpiInformation.pRxPacket, SPI_HEADER_SIZE-1, length);
/* read the remainder of the packet */
SpiReadDataSynchronous(sSpiInformation.pRxPacket + SPI_HEADER_SIZE, length);
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
}
void SpiReadHeader(void)
{
SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10);
}
void SpiTriggerRxProcessing(void)
{
SpiPauseSpi();
CS_HIGH();
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
// for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun
// occurred - and we will stuck here forever!
if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) {
while (1);
}
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
}
long SpiReadDataCont(void)
{
long data_to_recv=0;
unsigned char *evnt_buff, type;
//determine what type of packet we have
evnt_buff = sSpiInformation.pRxPacket;
STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
switch (type) {
case HCI_TYPE_DATA:{
// We need to read the rest of data..
STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE),
HCI_DATA_LENGTH_OFFSET, data_to_recv);
if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) {
data_to_recv++;
}
if (data_to_recv) {
SpiReadDataSynchronous(evnt_buff + 10, data_to_recv);
}
break;
}
case HCI_TYPE_EVNT: {
// Calculate the rest length of the data
STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE),
HCI_EVENT_LENGTH_OFFSET, data_to_recv);
data_to_recv -= 1;
// Add padding byte if needed
if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) {
data_to_recv++;
}
if (data_to_recv) {
SpiReadDataSynchronous(evnt_buff + 10, data_to_recv);
}
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
break;
}
}
return 0;
}
void SSIContReadOperation(void)
{
// The header was read - continue with the payload read
if (!SpiReadDataCont()) {
/* All the data was read - finalize handling by switching
to the task and calling from task Event Handler */
SpiTriggerRxProcessing();
}
}
STATIC mp_obj_t irq_callback(mp_obj_t line)
{
DEBUG_printf("<< IRQ; state=%lu >>\n", sSpiInformation.ulSpiState);
switch (sSpiInformation.ulSpiState) {
case eSPI_STATE_POWERUP:
/* This means IRQ line was low call a callback of HCI Layer to inform on event */
DEBUG_printf(" - POWERUP\n");
sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
break;
case eSPI_STATE_IDLE:
DEBUG_printf(" - IDLE\n");
sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;
/* IRQ line goes down - we are start reception */
CS_LOW();
// Wait for TX/RX Compete which will come as DMA interrupt
SpiReadHeader();
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
SSIContReadOperation();
break;
case eSPI_STATE_WRITE_IRQ:
DEBUG_printf(" - WRITE IRQ\n");
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
CS_HIGH();
break;
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(irq_callback_obj, irq_callback);

View File

@@ -12,23 +12,23 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
@@ -43,11 +43,6 @@
// INCLUDE FILES
//******************************************************************************
#include <stdint.h>
#include "mpconfigport.h"
#if MICROPY_HW_ENABLE_CC3K
#include "cc3000_common.h"
#include "string.h"
#include "hci.h"
@@ -114,22 +109,22 @@
#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10)
#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38)
#define GET_MSS_VAL_RETVAL_OFFSET (0)
//*****************************************************************************
// GLOBAL VARAIABLES
//*****************************************************************************
unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL;
UINT32 socket_active_status = SOCKET_STATUS_INIT_VAL;
//*****************************************************************************
// Prototypes for the static functions
//*****************************************************************************
static long hci_event_unsol_flowcontrol_handler(char *pEvent);
static INT32 hci_event_unsol_flowcontrol_handler(CHAR *pEvent);
static void update_socket_active_status(char *resp_params);
static void update_socket_active_status(CHAR *resp_params);
//*****************************************************************************
@@ -143,11 +138,11 @@ static void update_socket_active_status(char *resp_params);
//! @brief Handle unsolicited event from type patch request
//
//*****************************************************************************
void hci_unsol_handle_patch_request(char *event_hdr)
void hci_unsol_handle_patch_request(CHAR *event_hdr)
{
char *params = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
unsigned long ucLength = 0;
char *patch;
CHAR *params = (CHAR *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
UINT32 ucLength = 0;
CHAR *patch;
switch (*params)
{
@@ -159,15 +154,15 @@ void hci_unsol_handle_patch_request(char *event_hdr)
if (patch)
{
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
tSLInformation.pucTxCommandBuffer, patch, ucLength);
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
tSLInformation.pucTxCommandBuffer, patch, ucLength);
return;
}
}
// Send 0 length Patches response event
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
tSLInformation.pucTxCommandBuffer, 0, 0);
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
tSLInformation.pucTxCommandBuffer, 0, 0);
break;
case HCI_EVENT_PATCHES_FW_REQ:
@@ -179,15 +174,15 @@ void hci_unsol_handle_patch_request(char *event_hdr)
// Build and send a patch
if (patch)
{
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
tSLInformation.pucTxCommandBuffer, patch, ucLength);
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
tSLInformation.pucTxCommandBuffer, patch, ucLength);
return;
}
}
// Send 0 length Patches response event
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
tSLInformation.pucTxCommandBuffer, 0, 0);
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
tSLInformation.pucTxCommandBuffer, 0, 0);
break;
case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
@@ -198,15 +193,15 @@ void hci_unsol_handle_patch_request(char *event_hdr)
if (patch)
{
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
tSLInformation.pucTxCommandBuffer, patch, ucLength);
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
tSLInformation.pucTxCommandBuffer, patch, ucLength);
return;
}
}
// Send 0 length Patches response event
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
tSLInformation.pucTxCommandBuffer, 0, 0);
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
tSLInformation.pucTxCommandBuffer, 0, 0);
break;
}
}
@@ -229,42 +224,45 @@ void hci_unsol_handle_patch_request(char *event_hdr)
//*****************************************************************************
unsigned char *
hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
UINT8 * hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen)
{
unsigned char *pucReceivedData, ucArgsize;
unsigned short usLength;
unsigned char *pucReceivedParams;
unsigned short usReceivedEventOpcode = 0;
unsigned long retValue32;
unsigned char * RecvParams;
unsigned char *RetParams;
UINT8 *pucReceivedData, ucArgsize;
UINT16 usLength;
UINT8 *pucReceivedParams;
UINT16 usReceivedEventOpcode = 0;
UINT32 retValue32;
UINT8 * RecvParams;
UINT8 *RetParams;
while (1)
{
if (tSLInformation.usEventOrDataReceived != 0)
{
{
pucReceivedData = (tSLInformation.pucReceivedData);
if (*pucReceivedData == HCI_TYPE_EVNT)
{
// Event Received
STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode);
pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;
STREAM_TO_UINT16((CHAR *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET,
usReceivedEventOpcode);
pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;
RecvParams = pucReceivedParams;
RetParams = pRetParams;
// In case unsolicited event received - here the handling finished
if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
if (hci_unsol_event_handler((CHAR *)pucReceivedData) == 0)
{
STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);
switch(usReceivedEventOpcode)
{
{
case HCI_CMND_READ_BUFFER_SIZE:
{
STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers);
STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength);
STREAM_TO_UINT8((CHAR *)pucReceivedParams, 0,
tSLInformation.usNumberOfFreeBuffers);
STREAM_TO_UINT16((CHAR *)pucReceivedParams, 1,
tSLInformation.usSlBufferLength);
}
break;
@@ -281,7 +279,8 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
case HCI_NETAPP_PING_REPORT:
case HCI_EVNT_MDNS_ADVERTISE:
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams);
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
,*(UINT8 *)pRetParams);
break;
case HCI_CMND_SETSOCKOPT:
@@ -303,49 +302,58 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
case HCI_EVNT_CONNECT:
case HCI_EVNT_NVMEM_WRITE:
STREAM_TO_UINT32((char *)pucReceivedParams,0 ,*(unsigned long *)pRetParams);
STREAM_TO_UINT32((CHAR *)pucReceivedParams,0
,*(UINT32 *)pRetParams);
break;
case HCI_EVNT_READ_SP_VERSION:
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams);
pRetParams = ((char *)pRetParams) + 1;
STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32);
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
,*(UINT8 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 1;
STREAM_TO_UINT32((CHAR *)pucReceivedParams, 0, retValue32);
UINT32_TO_STREAM((UINT8 *)pRetParams, retValue32);
break;
case HCI_EVNT_BSD_GETHOSTBYNAME:
STREAM_TO_UINT32((char *)pucReceivedParams
,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams
,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams);
STREAM_TO_UINT32((CHAR *)pucReceivedParams
,GET_HOST_BY_NAME_RETVAL_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams
,GET_HOST_BY_NAME_ADDR_OFFSET,*(UINT32 *)pRetParams);
break;
case HCI_EVNT_GETMSSVALUE:
STREAM_TO_UINT16((CHAR *)pucReceivedParams
,GET_MSS_VAL_RETVAL_OFFSET,*(UINT16 *)pRetParams);
break;
case HCI_EVNT_ACCEPT:
{
STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET
,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams
,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,ACCEPT_SD_OFFSET
,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams
,ACCEPT_RETURN_STATUS_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
//This argument returns in network order
memcpy((unsigned char *)pRetParams,
pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
memcpy((UINT8 *)pRetParams,
pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
break;
}
case HCI_EVNT_RECV:
case HCI_EVNT_RECVFROM:
{
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams);
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(UINT32 *)pRetParams);
if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
{
@@ -354,26 +362,26 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
break;
}
case HCI_EVNT_SEND:
case HCI_EVNT_SEND:
case HCI_EVNT_SENDTO:
{
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
break;
}
case HCI_EVNT_SELECT:
{
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams);
{
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_STATUS_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_READFD_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,SELECT_EXFD_OFFSET,*(UINT32 *)pRetParams);
break;
}
@@ -381,20 +389,20 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);
//This argument returns in network order
memcpy((unsigned char *)pRetParams, pucReceivedParams, 4);
memcpy((UINT8 *)pRetParams, pucReceivedParams, 4);
break;
case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 4;
STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 2;
STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams);
pRetParams = ((char *)pRetParams) + 2;
memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
STREAM_TO_UINT32((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT32((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 4;
STREAM_TO_UINT16((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 2;
STREAM_TO_UINT16((CHAR *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(UINT32 *)pRetParams);
pRetParams = ((CHAR *)pRetParams) + 2;
memcpy((UINT8 *)pRetParams, (CHAR *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
break;
case HCI_CMND_SIMPLE_LINK_START:
@@ -414,21 +422,21 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read DHCP server
//Read DHCP server
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read DNS server
//Read DNS server
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read Mac address
//Read Mac address
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
RecvParams += 6;
//Read SSID
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
break;
}
}
@@ -438,22 +446,22 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
}
}
else
{
{
pucReceivedParams = pucReceivedData;
STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);
STREAM_TO_UINT8((CHAR *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);
STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);
STREAM_TO_UINT16((CHAR *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);
// Data received: note that the only case where from and from length
// Data received: note that the only case where from and from length
// are not null is in recv from, so fill the args accordingly
if (from)
{
STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen);
STREAM_TO_UINT32((CHAR *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(UINT32 *)fromlen);
memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
}
memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
usLength - ucArgsize);
usLength - ucArgsize);
tSLInformation.usRxDataPending = 0;
}
@@ -462,18 +470,18 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
SpiResumeSpi();
// Since we are going to TX - we need to handle this event after the
// Since we are going to TX - we need to handle this event after the
// ResumeSPi since we need interrupts
if ((*pucReceivedData == HCI_TYPE_EVNT) &&
(usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
(usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
{
hci_unsol_handle_patch_request((char *)pucReceivedData);
hci_unsol_handle_patch_request((CHAR *)pucReceivedData);
}
if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0))
{
return NULL;
}
}
}
}
@@ -491,13 +499,12 @@ hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
//! @brief Handle unsolicited events
//
//*****************************************************************************
long
hci_unsol_event_handler(char *event_hdr)
INT32 hci_unsol_event_handler(CHAR *event_hdr)
{
char * data = NULL;
long event_type;
unsigned long NumberOfReleasedPackets;
unsigned long NumberOfSentPackets;
CHAR * data = NULL;
INT32 event_type;
UINT32 NumberOfReleasedPackets;
UINT32 NumberOfSentPackets;
STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
@@ -519,7 +526,7 @@ hci_unsol_event_handler(char *event_hdr)
{
tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
}
}
}
return 1;
}
@@ -527,7 +534,7 @@ hci_unsol_event_handler(char *event_hdr)
}
if(event_type & HCI_EVNT_WLAN_UNSOL_BASE)
{
{
switch(event_type)
{
case HCI_EVNT_WLAN_KEEPALIVE:
@@ -544,10 +551,10 @@ hci_unsol_event_handler(char *event_hdr)
case HCI_EVNT_WLAN_UNSOL_DHCP:
{
unsigned char params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
unsigned char *recParams = params;
UINT8 params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
UINT8 *recParams = params;
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
//Read IP address
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
@@ -556,81 +563,81 @@ hci_unsol_event_handler(char *event_hdr)
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
data += 4;
//Read default GW
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
data += 4;
//Read DHCP server
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
//Read DHCP server
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
data += 4;
//Read DNS server
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
//Read DNS server
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
// read the status
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
if( tSLInformation.sWlanCB )
{
tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params));
tSLInformation.sWlanCB(event_type, (CHAR *)params, sizeof(params));
}
}
break;
case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
{
netapp_pingreport_args_t params;
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
netapp_pingreport_args_t params;
data = (CHAR*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
if( tSLInformation.sWlanCB )
{
tSLInformation.sWlanCB(event_type, (char *)&params, sizeof(params));
tSLInformation.sWlanCB(event_type, (CHAR *)&params, sizeof(params));
}
}
break;
case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
{
data = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
data = (CHAR *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
if( tSLInformation.sWlanCB )
{
//data[0] represents the socket id, for which FIN was received by remote.
//Upon receiving this event, the user can close the socket, or else the
//Upon receiving this event, the user can close the socket, or else the
//socket will be closded after inacvitity timeout (by default 60 seconds)
tSLInformation.sWlanCB(event_type, data, 1);
}
}
break;
//'default' case which means "event not supported"
default:
//'default' case which means "event not supported"
default:
return (0);
}
return(1);
}
if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO)
|| (event_type == HCI_EVNT_WRITE))
|| (event_type == HCI_EVNT_WRITE))
{
char *pArg;
long status;
CHAR *pArg;
INT32 status;
pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
if (ERROR_SOCKET_INACTIVE == status)
{
// The only synchronous event that can come from SL device in form of
// command complete is "Command Complete" on data sent, in case SL device
// was unable to transmit
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError);
update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
if (ERROR_SOCKET_INACTIVE == status)
{
// The only synchronous event that can come from SL device in form of
// command complete is "Command Complete" on data sent, in case SL device
// was unable to transmit
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError);
update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
return (1);
}
else
return (0);
return (1);
}
else
return (0);
}
//handle a case where unsolicited event arrived, but was not handled by any of the cases above
@@ -650,29 +657,28 @@ hci_unsol_event_handler(char *event_hdr)
//!
//! @return ESUCCESS if successful, EFAIL if an error occurred
//!
//! @brief Parse the incoming unsolicited event packets and issues
//! @brief Parse the incoming unsolicited event packets and issues
//! corresponding event handler.
//
//*****************************************************************************
long
hci_unsolicited_event_handler(void)
INT32 hci_unsolicited_event_handler(void)
{
unsigned long res = 0;
unsigned char *pucReceivedData;
UINT32 res = 0;
UINT8 *pucReceivedData;
if (tSLInformation.usEventOrDataReceived != 0)
{
pucReceivedData = (tSLInformation.pucReceivedData);
if (*pucReceivedData == HCI_TYPE_EVNT)
{
{
// In case unsolicited event received - here the handling finished
if (hci_unsol_event_handler((char *)pucReceivedData) == 1)
if (hci_unsol_event_handler((CHAR *)pucReceivedData) == 1)
{
// There was an unsolicited event received - we can release the buffer
// and clean the event received
// and clean the event received
tSLInformation.usEventOrDataReceived = 0;
res = 1;
@@ -692,11 +698,11 @@ hci_unsolicited_event_handler(void)
//! @param Status
//! @return none
//!
//! @brief Check if the socket ID and status are valid and set
//! @brief Check if the socket ID and status are valid and set
//! accordingly the global socket status
//
//*****************************************************************************
void set_socket_active_status(long Sd, long Status)
void set_socket_active_status(INT32 Sd, INT32 Status)
{
if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status))
{
@@ -719,25 +725,24 @@ void set_socket_active_status(long Sd, long Status)
//! number of free buffer in the SL device.
//
//*****************************************************************************
long
hci_event_unsol_flowcontrol_handler(char *pEvent)
INT32 hci_event_unsol_flowcontrol_handler(CHAR *pEvent)
{
long temp, value;
unsigned short i;
unsigned short pusNumberOfHandles=0;
char *pReadPayload;
INT32 temp, value;
UINT16 i;
UINT16 pusNumberOfHandles=0;
CHAR *pReadPayload;
STREAM_TO_UINT16((char *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
pReadPayload = ((char *)pEvent +
HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
STREAM_TO_UINT16((CHAR *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
pReadPayload = ((CHAR *)pEvent +
HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
temp = 0;
for(i = 0; i < pusNumberOfHandles ; i++)
{
STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
temp += value;
pReadPayload += FLOW_CONTROL_EVENT_SIZE;
pReadPayload += FLOW_CONTROL_EVENT_SIZE;
}
tSLInformation.usNumberOfFreeBuffers += temp;
@@ -751,14 +756,13 @@ hci_event_unsol_flowcontrol_handler(char *pEvent)
//! get_socket_active_status
//!
//! @param Sd Socket IS
//! @return Current status of the socket.
//! @return Current status of the socket.
//!
//! @brief Retrieve socket status
//
//*****************************************************************************
long
get_socket_active_status(long Sd)
INT32 get_socket_active_status(INT32 Sd)
{
if(M_IS_VALID_SD(Sd))
{
@@ -772,15 +776,14 @@ get_socket_active_status(long Sd)
//! update_socket_active_status
//!
//! @param resp_params Socket IS
//! @return Current status of the socket.
//! @return Current status of the socket.
//!
//! @brief Retrieve socket status
//
//*****************************************************************************
void
update_socket_active_status(char *resp_params)
void update_socket_active_status(CHAR *resp_params)
{
long status, sd;
INT32 status, sd;
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
@@ -806,10 +809,9 @@ update_socket_active_status(char *resp_params)
//
//*****************************************************************************
void
SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams)
void SimpleLinkWaitEvent(UINT16 usOpcode, void *pRetParams)
{
// In the blocking implementation the control to caller will be returned only
// In the blocking implementation the control to caller will be returned only
// after the end of current transaction
tSLInformation.usRxEventOpcode = usOpcode;
hci_event_handler(pRetParams, 0, 0);
@@ -826,16 +828,14 @@ SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams)
//! @return none
//!
//! @brief Wait for data, pass it to the hci_event_handler
//! and update in a global variable that there is
//! and update in a global variable that there is
//! data to read.
//
//*****************************************************************************
void
SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from,
unsigned char *fromlen)
void SimpleLinkWaitData(UINT8 *pBuf, UINT8 *from, UINT8 *fromlen)
{
// In the blocking implementation the control to caller will be returned only
// In the blocking implementation the control to caller will be returned only
// after the end of current transaction, i.e. only after data will be received
tSLInformation.usRxDataPending = 1;
hci_event_handler(pBuf, from, fromlen);
@@ -847,5 +847,3 @@ SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from,
//! @}
//
//*****************************************************************************
#endif // MICROPY_HW_ENABLE_CC3K

View File

@@ -12,23 +12,23 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
@@ -40,12 +40,7 @@
//
//*****************************************************************************
#include <stdint.h>
#include <string.h> // for memcpy
#include "mpconfigport.h"
#if MICROPY_HW_ENABLE_CC3K
#include <string.h>
#include "cc3000_common.h"
#include "hci.h"
#include "ccspi.h"
@@ -68,11 +63,9 @@
//! @brief Initiate an HCI command.
//
//*****************************************************************************
unsigned short
hci_command_send(unsigned short usOpcode, unsigned char *pucBuff,
unsigned char ucArgsLength)
{
unsigned char *stream;
UINT16 hci_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength)
{
UINT8 *stream;
stream = (pucBuff + SPI_HEADER_SIZE);
@@ -101,15 +94,14 @@ hci_command_send(unsigned short usOpcode, unsigned char *pucBuff,
//! @brief Initiate an HCI data write operation
//
//*****************************************************************************
long
hci_data_send(unsigned char ucOpcode,
unsigned char *ucArgs,
unsigned short usArgsLength,
unsigned short usDataLength,
const unsigned char *ucTail,
unsigned short usTailLength)
INT32 hci_data_send(UINT8 ucOpcode,
UINT8 *ucArgs,
UINT16 usArgsLength,
UINT16 usDataLength,
const UINT8 *ucTail,
UINT16 usTailLength)
{
unsigned char *stream;
UINT8 *stream;
stream = ((ucArgs) + SPI_HEADER_SIZE);
@@ -139,10 +131,9 @@ hci_data_send(unsigned char ucOpcode,
//! @brief Prepeare HCI header and initiate an HCI data write operation
//
//*****************************************************************************
void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
unsigned char ucArgsLength,unsigned short ucDataLength)
{
unsigned char *stream = (pucBuff + SPI_HEADER_SIZE);
void hci_data_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength,UINT16 ucDataLength)
{
UINT8 *stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
UINT8_TO_STREAM(stream, usOpcode);
@@ -161,7 +152,7 @@ void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
//!
//! @param usOpcode command operation code
//! @param pucBuff pointer to the command's arguments buffer
//! @param patch pointer to patch content buffer
//! @param patch pointer to patch content buffer
//! @param usDataLength data length
//!
//! @return none
@@ -169,12 +160,11 @@ void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
//! @brief Prepeare HCI header and initiate an HCI patch write operation
//
//*****************************************************************************
void
hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength)
{
unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE);
unsigned short usTransLength;
unsigned char *stream = (pucBuff + SPI_HEADER_SIZE);
void hci_patch_send(UINT8 ucOpcode, UINT8 *pucBuff, CHAR *patch, UINT16 usDataLength)
{
UINT8 *data_ptr = (pucBuff + SPI_HEADER_SIZE);
UINT16 usTransLength;
UINT8 *stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
UINT8_TO_STREAM(stream, ucOpcode);
@@ -216,12 +206,12 @@ hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsi
usDataLength -= usTransLength;
}
*(unsigned short *)data_ptr = usTransLength;
*(UINT16 *)data_ptr = usTransLength;
memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength);
patch += usTransLength;
// Update the opcode of the event we will be waiting for
SpiWrite((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength));
SpiWrite((UINT8 *)data_ptr, usTransLength + sizeof(usTransLength));
}
}
}
@@ -233,5 +223,3 @@ hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsi
//
//
//*****************************************************************************
#endif // MICROPY_HW_ENABLE_CC3K

View File

@@ -0,0 +1,196 @@
/*
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <std.h>
#include <string.h>
#include "cc3000_common.h"
#include "socket.h"
#include "inet_ntop.h"
#define IN6ADDRSZ 16
#define INADDRSZ 4
#define INT16SZ 2
#define ENOSPC (28)
#define EAFNOSUPPORT (106)
#define SET_ERRNO(err) (CC3000_EXPORT(errno)=-err)
/*
* Format an IPv4 address, more or less like inet_ntoa().
*
* Returns `dst' (as a const)
* Note:
* - uses no statics
* - takes a unsigned char* not an in_addr as input
*/
static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
{
size_t len;
char tmp[sizeof "255.255.255.255"];
tmp[0] = '\0';
(void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
((int)((unsigned char)src[3])) & 0xff,
((int)((unsigned char)src[2])) & 0xff,
((int)((unsigned char)src[1])) & 0xff,
((int)((unsigned char)src[0])) & 0xff);
len = strlen(tmp);
if(len == 0 || len >= size)
{
SET_ERRNO(ENOSPC);
return (NULL);
}
strcpy(dst, tmp);
return dst;
}
#ifdef ENABLE_IPV6
/*
* Convert IPv6 binary address into presentation (printable) format.
*/
static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
char *tp;
struct {
long base;
long len;
} best, cur;
unsigned long words[IN6ADDRSZ / INT16SZ];
int i;
/* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof(words));
for (i = 0; i < IN6ADDRSZ; i++)
words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
best.len = 0;
cur.len = 0;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
{
if(words[i] == 0)
{
if(cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
}
else if(cur.base != -1)
{
if(best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
best = cur;
if(best.base != -1 && best.len < 2)
best.base = -1;
/* Format the result.
*/
tp = tmp;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
{
/* Are we inside the best run of 0x00's?
*/
if(best.base != -1 && i >= best.base && i < (best.base + best.len))
{
if(i == best.base)
*tp++ = ':';
continue;
}
/* Are we following an initial run of 0x00s or any real hex?
*/
if(i != 0)
*tp++ = ':';
/* Is this address an encapsulated IPv4?
*/
if(i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
{
if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
{
SET_ERRNO(ENOSPC);
return (NULL);
}
tp += strlen(tp);
break;
}
tp += snprintf(tp, 5, "%lx", words[i]);
}
/* Was it a trailing run of 0x00's?
*/
if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
*tp++ = ':';
*tp++ = '\0';
/* Check for overflow, copy, and we're done.
*/
if((size_t)(tp - tmp) > size)
{
SET_ERRNO(ENOSPC);
return (NULL);
}
strcpy(dst, tmp);
return dst;
}
#endif /* ENABLE_IPV6 */
/*
* Convert a network format address to presentation format.
*
* Returns pointer to presentation format address (`buf').
* Returns NULL on error and errno set with the specific
* error, EAFNOSUPPORT or ENOSPC.
*
* On Windows we store the error in the thread errno, not
* in the winsock error code. This is to avoid loosing the
* actual last winsock error. So use macro ERRNO to fetch the
* errno this funtion sets when returning NULL, not SOCKERRNO.
*/
char *inet_ntop(int af, const void *src, char *buf, size_t size)
{
switch (af) {
case AF_INET:
return inet_ntop4((const unsigned char*)src, buf, size);
#ifdef ENABLE_IPV6
case AF_INET6:
return inet_ntop6((const unsigned char*)src, buf, size);
#endif
default:
SET_ERRNO(EAFNOSUPPORT);
return NULL;
}
}

View File

@@ -0,0 +1,216 @@
/* This is from the BIND 4.9.4 release, modified to compile by itself */
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <string.h>
#include "cc3000_common.h"
#include "socket.h"
#include "inet_pton.h"
#define IN6ADDRSZ 16
#define INADDRSZ 4
#define INT16SZ 2
static int inet_pton4(const char *src, unsigned char *dst);
#ifdef ENABLE_IPV6
static int inet_pton6(const char *src, unsigned char *dst);
#endif
#define EAFNOSUPPORT (106)
#define SET_ERRNO(err) (CC3000_EXPORT(errno)=-err)
/* int
* inet_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
* notice:
* On Windows we store the error in the thread errno, not
* in the winsock error code. This is to avoid loosing the
* actual last winsock error. So use macro ERRNO to fetch the
* errno this funtion sets when returning (-1), not SOCKERRNO.
* author:
* Paul Vixie, 1996.
*/
int inet_pton(int af, const char *src, void *dst)
{
switch (af) {
case AF_INET:
return (inet_pton4(src, (unsigned char *)dst));
#ifdef ENABLE_IPV6
case AF_INET6:
return (inet_pton6(src, (unsigned char *)dst));
#endif
default:
SET_ERRNO(EAFNOSUPPORT);
return (-1);
}
/* NOTREACHED */
}
/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
static int inet_pton4(const char *src, unsigned char *dst)
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
tp = tmp;
*tp = 0;
while((ch = *src++) != '\0') {
const char *pch;
if((pch = strchr(digits, ch)) != NULL) {
unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
if(saw_digit && *tp == 0)
return (0);
if(val > 255)
return (0);
*tp = (unsigned char)val;
if(! saw_digit) {
if(++octets > 4)
return (0);
saw_digit = 1;
}
}
else if(ch == '.' && saw_digit) {
if(octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
}
else
return (0);
}
if(octets < 4)
return (0);
memcpy(dst, tmp, INADDRSZ);
return (1);
}
#ifdef ENABLE_IPV6
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
static int inet_pton6(const char *src, unsigned char *dst)
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
unsigned int val;
memset((tp = tmp), 0, IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if(*src == ':')
if(*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while((ch = *src++) != '\0') {
const char *pch;
if((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if(pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if(++saw_xdigit > 4)
return (0);
continue;
}
if(ch == ':') {
curtok = src;
if(!saw_xdigit) {
if(colonp)
return (0);
colonp = tp;
continue;
}
if(tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if(saw_xdigit) {
if(tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if(colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const long n = tp - colonp;
long i;
if(tp == endp)
return (0);
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if(tp != endp)
return (0);
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
}
#endif /* ENABLE_IPV6 */

View File

@@ -12,42 +12,39 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include <stdint.h>
#include "mpconfigport.h"
#if MICROPY_HW_ENABLE_CC3K
#include <string.h>
#include "netapp.h"
#include "hci.h"
#include "socket.h"
#include "evnt_handler.h"
#include "nvmem.h"
#define MIN_TIMER_VAL_SECONDS 20
#define MIN_TIMER_VAL_SECONDS 10
#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
{ \
t = MIN_TIMER_VAL_SECONDS; \
}
{ \
t = MIN_TIMER_VAL_SECONDS; \
}
#define NETAPP_DHCP_PARAMS_LEN (20)
@@ -60,17 +57,17 @@
//
//! netapp_config_mac_adrress
//!
//! @param mac device mac address, 6 bytes. Saved: yes
//! @param mac device mac address, 6 bytes. Saved: yes
//!
//! @return return on success 0, otherwise error.
//!
//! @brief Configure device MAC address and store it in NVMEM.
//! @brief Configure device MAC address and store it in NVMEM.
//! The value of the MAC address configured through the API will
//! be stored in CC3000 non volatile memory, thus preserved
//! be stored in CC3000 non volatile memory, thus preserved
//! over resets.
//
//*****************************************************************************
long netapp_config_mac_adrress(unsigned char * mac)
INT32 netapp_config_mac_adrress(UINT8 * mac)
{
return nvmem_set_mac_address(mac);
}
@@ -79,33 +76,33 @@ long netapp_config_mac_adrress(unsigned char * mac)
//
//! netapp_dhcp
//!
//! @param aucIP device mac address, 6 bytes. Saved: yes
//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes
//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes
//! @param aucDNSServer device mac address, 6 bytes. Saved: yes
//! @param aucIP device mac address, 6 bytes. Saved: yes
//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes
//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes
//! @param aucDNSServer device mac address, 6 bytes. Saved: yes
//!
//! @return return on success 0, otherwise error.
//!
//! @brief netapp_dhcp is used to configure the network interface,
//! static or dynamic (DHCP).\n In order to activate DHCP mode,
//! @brief netapp_dhcp is used to configure the network interface,
//! static or dynamic (DHCP).\n In order to activate DHCP mode,
//! aucIP, aucSubnetMask, aucDefaultGateway must be 0.
//! The default mode of CC3000 is DHCP mode.
//! Note that the configuration is saved in non volatile memory
//! and thus preserved over resets.
//!
//! @note If the mode is altered a reset of CC3000 device is required
//! in order to apply changes.\nAlso note that asynchronous event
//! of DHCP_EVENT, which is generated when an IP address is
//! allocated either by the DHCP server or due to static
//! allocation is generated only upon a connection to the
//! AP was established.
//!
//! @note If the mode is altered a reset of CC3000 device is required
//! in order to apply changes.\nAlso note that asynchronous event
//! of DHCP_EVENT, which is generated when an IP address is
//! allocated either by the DHCP server or due to static
//! allocation is generated only upon a connection to the
//! AP was established.
//!
//*****************************************************************************
long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer)
INT32 netapp_dhcp(UINT32 *aucIP, UINT32 *aucSubnetMask,UINT32 *aucDefaultGateway, UINT32 *aucDNSServer)
{
signed char scRet;
unsigned char *ptr;
unsigned char *args;
INT8 scRet;
UINT8 *ptr;
UINT8 *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
@@ -132,30 +129,30 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned lon
//
//! netapp_timeout_values
//!
//! @param aucDHCP DHCP lease time request, also impact
//! @param aucDHCP DHCP lease time request, also impact
//! the DHCP renew timeout. Range: [0-0xffffffff] seconds,
//! 0 or 0xffffffff == infinity lease timeout.
//! Resolution:10 seconds. Influence: only after
//! reconnecting to the AP.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
//! The parameter is saved into the CC3000 NVMEM.
//! Resolution:10 seconds. Influence: only after
//! reconnecting to the AP.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds.
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 14400 seconds.
//!
//!
//! @param aucARP ARP refresh timeout, if ARP entry is not updated by
//! incoming packet, the ARP entry will be deleted by
//! the end of the timeout.
//! the end of the timeout.
//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
//! Resolution: 10 seconds. Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds
//! The parameter is saved into the CC3000 NVMEM.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 seconds
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 3600 seconds.
//!
//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout
//! Range: [0-0xffffffff] seconds, 0 == infinity timeout
//! Resolution: 10 seconds.
//! Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
//! The parameter is saved into the CC3000 NVMEM.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 10 seconds.
//!
//! @param aucInactivity Socket inactivity timeout, socket timeout is
@@ -163,41 +160,40 @@ long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned lon
//! end of the socket timeout the socket will be closed
//! Range: [0-0xffffffff] sec, 0 == infinity timeout.
//! Resolution: 10 seconds. Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
//! The parameter is saved into the CC3000 NVMEM.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 10 sec
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 60 seconds.
//!
//! @return return on success 0, otherwise error.
//!
//! @brief Set new timeout values. Function set new timeout values for:
//! DHCP lease timeout, ARP refresh timeout, keepalive event
//! timeout and socket inactivity timeout
//!
//! @note If a parameter set to non zero value which is less than 20s,
//! it will be set automatically to 20s.
//! @brief Set new timeout values. Function set new timeout values for:
//! DHCP lease timeout, ARP refresh timeout, keepalive event
//! timeout and socket inactivity timeout
//!
//! @note If a parameter set to non zero value which is less than 10s,
//! it will be set automatically to 10s.
//!
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
long
netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity)
INT32 netapp_timeout_values(UINT32 *aucDHCP, UINT32 *aucARP,UINT32 *aucKeepalive, UINT32 *aucInactivity)
{
signed char scRet;
unsigned char *ptr;
unsigned char *args;
INT8 scRet;
UINT8 *ptr;
UINT8 *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
// Set minimal values of timers
// Set minimal values of timers
MIN_TIMER_SET(*aucDHCP)
MIN_TIMER_SET(*aucARP)
MIN_TIMER_SET(*aucKeepalive)
MIN_TIMER_SET(*aucInactivity)
MIN_TIMER_SET(*aucARP)
MIN_TIMER_SET(*aucKeepalive)
MIN_TIMER_SET(*aucInactivity)
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, *aucDHCP);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, *aucDHCP);
args = UINT32_TO_STREAM(args, *aucARP);
args = UINT32_TO_STREAM(args, *aucKeepalive);
args = UINT32_TO_STREAM(args, *aucInactivity);
@@ -219,27 +215,27 @@ netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned lon
//!
//! @param ip destination IP address
//! @param pingAttempts number of echo requests to send
//! @param pingSize send buffer size which may be up to 1400 bytes
//! @param pingSize send buffer size which may be up to 1400 bytes
//! @param pingTimeout Time to wait for a response,in milliseconds.
//!
//! @return return on success 0, otherwise error.
//!
//! @brief send ICMP ECHO_REQUEST to network hosts
//!
//! @note If an operation finished successfully asynchronous ping report
//! @brief send ICMP ECHO_REQUEST to network hosts
//!
//! @note If an operation finished successfully asynchronous ping report
//! event will be generated. The report structure is as defined
//! by structure netapp_pingreport_args_t.
//!
//! @warning Calling this function while a previous Ping Requests are in
//! @warning Calling this function while a previous Ping Requests are in
//! progress will stop the previous ping request.
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
long
netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout)
INT32
netapp_ping_send(UINT32 *ip, UINT32 ulPingAttempts, UINT32 ulPingSize, UINT32 ulPingTimeout)
{
signed char scRet;
unsigned char *ptr, *args;
INT8 scRet;
UINT8 *ptr, *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
@@ -269,7 +265,7 @@ netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long
//!
//! @return none
//!
//! @brief Request for ping status. This API triggers the CC3000 to send
//! @brief Request for ping status. This API triggers the CC3000 to send
//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.
//! This event will carry the report structure:
//! netapp_pingreport_args_t. This structure is filled in with ping
@@ -278,8 +274,8 @@ netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long
//! packets_received - echo reply, min_round_time - minimum
//! round time, max_round_time - max round time,
//! avg_round_time - average round time
//!
//! @note When a ping operation is not active, the returned structure
//!
//! @note When a ping operation is not active, the returned structure
//! fields are 0.
//!
//*****************************************************************************
@@ -288,9 +284,9 @@ netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long
#ifndef CC3000_TINY_DRIVER
void netapp_ping_report()
{
unsigned char *ptr;
UINT8 *ptr;
ptr = tSLInformation.pucTxCommandBuffer;
signed char scRet;
INT8 scRet;
scRet = EFAIL;
@@ -298,7 +294,7 @@ void netapp_ping_report()
hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet);
SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet);
}
#endif
@@ -308,18 +304,18 @@ void netapp_ping_report()
//!
//! @param none
//!
//! @return On success, zero is returned. On error, -1 is returned.
//! @return On success, zero is returned. On error, -1 is returned.
//!
//! @brief Stop any ping request.
//!
//!
//!
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
long netapp_ping_stop()
INT32 netapp_ping_stop()
{
signed char scRet;
unsigned char *ptr;
INT8 scRet;
UINT8 *ptr;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
@@ -338,7 +334,7 @@ long netapp_ping_stop()
//
//! netapp_ipconfig
//!
//! @param[out] ipconfig This argument is a pointer to a
//! @param[out] ipconfig This argument is a pointer to a
//! tNetappIpconfigRetArgs structure. This structure is
//! filled in with the network interface configuration.
//! tNetappIpconfigRetArgs:\n aucIP - ip address,
@@ -353,7 +349,7 @@ long netapp_ping_stop()
//! Note that the information is available only after the WLAN
//! connection was established. Calling this function before
//! associated, will cause non-defined values to be returned.
//!
//!
//! @note The function is useful for figuring out the IP Configuration of
//! the device when DHCP is used and for figuring out the SSID of
//! the Wireless network the device is associated with.
@@ -363,7 +359,7 @@ long netapp_ping_stop()
#ifndef CC3000_TINY_DRIVER
void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
{
unsigned char *ptr;
UINT8 *ptr;
ptr = tSLInformation.pucTxCommandBuffer;
@@ -394,10 +390,10 @@ void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
long netapp_arp_flush(void)
INT32 netapp_arp_flush(void)
{
signed char scRet;
unsigned char *ptr;
INT8 scRet;
UINT8 *ptr;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
@@ -432,34 +428,32 @@ long netapp_arp_flush(void)
#ifndef CC3000_TINY_DRIVER
long netapp_set_debug_level(unsigned long ulLevel)
INT32 netapp_set_debug_level(UINT32 ulLevel)
{
signed char scRet;
unsigned char *ptr, *args;
INT8 scRet;
UINT8 *ptr, *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
//
// Fill in temporary command buffer
//
args = UINT32_TO_STREAM(args, ulLevel);
//
// Fill in temporary command buffer
//
args = UINT32_TO_STREAM(args, ulLevel);
//
// Initiate a HCI command
//
hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN);
//
// Initiate a HCI command
//
hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN);
//
//
// Wait for command complete event
//
SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet);
return(scRet);
return(scRet);
}
#endif
#endif // MICROPY_HW_ENABLE_CC3K

View File

@@ -12,23 +12,23 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
@@ -40,12 +40,7 @@
//
//*****************************************************************************
#include <stdint.h>
#include <string.h>
#include "mpconfigport.h"
#if MICROPY_HW_ENABLE_CC3K
#include "nvmem.h"
#include "hci.h"
#include "socket.h"
@@ -73,24 +68,23 @@
//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
//! and user files 12-15.
//! @param ulLength number of bytes to read
//! @param ulOffset ulOffset in file from where to read
//! @param ulLength number of bytes to read
//! @param ulOffset ulOffset in file from where to read
//! @param buff output buffer pointer
//!
//! @return number of bytes read, otherwise error.
//! @return on success 0, error otherwise.
//!
//! @brief Reads data from the file referred by the ulFileId parameter.
//! @brief Reads data from the file referred by the ulFileId parameter.
//! Reads data from file ulOffset till length. Err if the file can't
//! be used, is invalid, or if the read is out of bounds.
//!
//! be used, is invalid, or if the read is out of bounds.
//!
//*****************************************************************************
signed long
nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, unsigned char *buff)
INT32 nvmem_read(UINT32 ulFileId, UINT32 ulLength, UINT32 ulOffset, UINT8 *buff)
{
unsigned char ucStatus = 0xFF;
unsigned char *ptr;
unsigned char *args;
UINT8 ucStatus = 0xFF;
UINT8 *ptr;
UINT8 *args;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
@@ -105,9 +99,9 @@ nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffse
SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus);
// In case there is data - read it - even if an error code is returned
// Note: It is the user responsibility to ignore the data in case of an error code
// Note: It is the user responsibility to ignore the data in case of an error code
// Wait for the data in a synchronous way. Here we assume that the buffer is
// Wait for the data in a synchronous way. Here we assume that the buffer is
// big enough to store also parameters of nvmem
SimpleLinkWaitData(buff, 0, 0);
@@ -123,27 +117,25 @@ nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffse
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
//! and user files 12-15.
//! @param ulLength number of bytes to write
//! @param ulEntryOffset offset in file to start write operation from
//! @param ulLength number of bytes to write
//! @param ulEntryOffset offset in file to start write operation from
//! @param buff data to write
//!
//! @return on success 0, error otherwise.
//!
//! @brief Write data to nvmem.
//! writes data to file referred by the ulFileId parameter.
//! Writes data to file ulOffset till ulLength.The file id will be
//! writes data to file referred by the ulFileId parameter.
//! Writes data to file ulOffset till ulLength.The file id will be
//! marked invalid till the write is done. The file entry doesn't
//! need to be valid - only allocated.
//!
//!
//*****************************************************************************
signed long
nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long
ulEntryOffset, unsigned char *buff)
INT32 nvmem_write(UINT32 ulFileId, UINT32 ulLength, UINT32 ulEntryOffset, UINT8 *buff)
{
long iRes;
unsigned char *ptr;
unsigned char *args;
INT32 iRes;
UINT8 *ptr;
UINT8 *args;
iRes = EFAIL;
@@ -156,12 +148,12 @@ nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long
args = UINT32_TO_STREAM(args, ulLength);
args = UINT32_TO_STREAM(args, ulEntryOffset);
memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE +
NVMEM_WRITE_PARAMS_LEN),buff,ulLength);
memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE +
NVMEM_WRITE_PARAMS_LEN),buff,ulLength);
// Initiate a HCI command but it will come on data channel
hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN,
ulLength);
ulLength);
SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes);
@@ -177,12 +169,12 @@ nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long
//!
//! @return on success 0, error otherwise.
//!
//! @brief Write MAC address to EEPROM.
//! @brief Write MAC address to EEPROM.
//! mac address as appears over the air (OUI first)
//!
//!
//*****************************************************************************
unsigned char nvmem_set_mac_address(unsigned char *mac)
UINT8 nvmem_set_mac_address(UINT8 *mac)
{
return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
}
@@ -191,16 +183,16 @@ unsigned char nvmem_set_mac_address(unsigned char *mac)
//
//! nvmem_get_mac_address
//!
//! @param[out] mac mac address
//! @param[out] mac mac address
//!
//! @return on success 0, error otherwise.
//!
//! @brief Read MAC address from EEPROM.
//! @brief Read MAC address from EEPROM.
//! mac address as appears over the air (OUI first)
//!
//!
//*****************************************************************************
unsigned char nvmem_get_mac_address(unsigned char *mac)
UINT8 nvmem_get_mac_address(UINT8 *mac)
{
return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
}
@@ -211,23 +203,23 @@ unsigned char nvmem_get_mac_address(unsigned char *mac)
//!
//! @param ulFileId nvmem file id:\n
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
//! @param spLength number of bytes to write
//! @param spLength number of bytes to write
//! @param spData SP data to write
//!
//! @return on success 0, error otherwise.
//!
//! @brief program a patch to a specific file ID.
//! @brief program a patch to a specific file ID.
//! The SP data is assumed to be organized in 2-dimensional.
//! Each line is SP_PORTION_SIZE bytes long. Actual programming is
//! Each line is SP_PORTION_SIZE bytes long. Actual programming is
//! applied in SP_PORTION_SIZE bytes portions.
//!
//!
//*****************************************************************************
unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData)
UINT8 nvmem_write_patch(UINT32 ulFileId, UINT32 spLength, const UINT8 *spData)
{
unsigned char status = 0;
unsigned short offset = 0;
unsigned char* spDataPtr = (unsigned char*)spData;
UINT8 status = 0;
UINT16 offset = 0;
UINT8* spDataPtr = (UINT8*)spData;
while ((status == 0) && (spLength >= SP_PORTION_SIZE))
{
@@ -256,33 +248,33 @@ unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength,
//
//! nvmem_read_sp_version
//!
//! @param[out] patchVer first number indicates package ID and the second
//! number indicates package build number
//! @param[out] patchVer first number indicates package ID and the second
//! number indicates package build number
//!
//! @return on success 0, error otherwise.
//!
//! @brief Read patch version. read package version (WiFi FW patch,
//! @brief Read patch version. read package version (WiFi FW patch,
//! driver-supplicant-NS patch, bootloader patch)
//!
//!
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
unsigned char nvmem_read_sp_version(unsigned char* patchVer)
UINT8 nvmem_read_sp_version(UINT8* patchVer)
{
unsigned char *ptr;
UINT8 *ptr;
// 1st byte is the status and the rest is the SP version
unsigned char retBuf[5];
UINT8 retBuf[5];
ptr = tSLInformation.pucTxCommandBuffer;
// Initiate a HCI command, no args are required
hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);
// Initiate a HCI command, no args are required
hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);
SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf);
// package ID
*patchVer = retBuf[3];
*patchVer = retBuf[3];
// package build number
*(patchVer+1) = retBuf[4];
*(patchVer+1) = retBuf[4];
return(retBuf[0]);
}
@@ -296,27 +288,26 @@ unsigned char nvmem_read_sp_version(unsigned char* patchVer)
//! * NVMEM_AES128_KEY_FILEID: 12
//! * NVMEM_SHARED_MEM_FILEID: 13
//! * and fileIDs 14 and 15
//! @param ulNewLen entry ulLength
//! @param ulNewLen entry ulLength
//!
//! @return on success 0, error otherwise.
//!
//! @brief Create new file entry and allocate space on the NVMEM.
//! @brief Create new file entry and allocate space on the NVMEM.
//! Applies only to user files.
//! Modify the size of file.
//! If the entry is unallocated - allocate it to size
//! If the entry is unallocated - allocate it to size
//! ulNewLen (marked invalid).
//! If it is allocated then deallocate it first.
//! To just mark the file as invalid without resizing -
//! To just mark the file as invalid without resizing -
//! set ulNewLen=0.
//!
//!
//*****************************************************************************
signed long
nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen)
INT32 nvmem_create_entry(UINT32 ulFileId, UINT32 ulNewLen)
{
unsigned char *ptr;
unsigned char *args;
unsigned short retval;
UINT8 *ptr;
UINT8 *args;
UINT8 retval;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
@@ -341,5 +332,3 @@ nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen)
//! @}
//
//*****************************************************************************
#endif // MICROPY_HW_ENABLE_CC3K

117
drivers/cc3000/src/patch.c Normal file
View File

@@ -0,0 +1,117 @@
/*****************************************************************************
*
* {PatchProgrammer_DR_Patch.c}
*
* Burn Patches to EEPROM
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
* ALL RIGHTS RESERVED
*
*****************************************************************************/
//
// Service Pack version P1.13.7.15.28 - Driver patches
// This file contains the CC3K driver and firmware patches
// From CC3000-FRAM-PATCH V:1.13.7 15-MAY-2014
unsigned short fw_length = 5700;
unsigned short drv_length = 8024;
const unsigned char wlan_drv_patch[8024] = { 0x00, 0x01, 0x00, 0x00, 0x50, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x18, 0x00, 0xE4, 0x62, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7A, 0x63, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x64, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20, 0x0C, 0x49, 0x08, 0x60, 0x0C, 0x48, 0x19, 0x30, 0xF7, 0x46, 0x30, 0xB5, 0x05, 0x1C, 0xAC, 0x69, 0x68, 0x68, 0x5F, 0x30, 0x09, 0xD1, 0x60, 0x6B, 0x0C, 0x38, 0x01, 0x21, 0x8E, 0x46, 0x06, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x00, 0x20, 0x60, 0x63, 0xAC, 0x69, 0x6C, 0x60, 0x04, 0x48, 0x5B, 0x30, 0x30, 0xBD, 0x40, 0x3B, 0x08, 0x00, 0x49, 0xD0, 0x01, 0x00, 0x09, 0xEA, 0x02, 0x00, 0x91, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA6, 0x64, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3C, 0x65, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xB5, 0x85, 0xB0, 0x05, 0x1C, 0xA8, 0x88, 0x00, 0x90, 0x28, 0x89, 0x01, 0x90, 0xE9, 0x68, 0x02, 0x91, 0x28, 0x7C, 0x03, 0x90, 0x2A, 0x6A, 0x00, 0x20, 0x17, 0x56, 0x68, 0x60, 0x00, 0x29, 0x4C, 0xD0, 0x00, 0x2F, 0x4A, 0xDC ,
0xCA, 0x49, 0x0C, 0x1C, 0x08, 0x26, 0x04, 0x90, 0x21, 0x88, 0x00, 0x98, 0x81, 0x42, 0x0C, 0xD1, 0x62, 0x88, 0x01, 0x98, 0x82, 0x42, 0x08, 0xD1, 0x46, 0x20, 0x02, 0x5D, 0x03, 0x98, 0x82, 0x42, 0x03, 0xD1, 0x0E, 0x20, 0x00, 0x57, 0xB8, 0x42, 0x0A, 0xD0, 0x46, 0x20, 0x00, 0x5D, 0x11, 0x28, 0x22, 0xD1, 0x00, 0x98, 0x81, 0x42, 0x1F, 0xD1, 0x0E, 0x20, 0x00, 0x57, 0xFF, 0xFF, 0xD2, 0x65, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xB8, 0x42, 0x1B, 0xD1, 0x04, 0x20, 0x02, 0x1C, 0x02, 0x98, 0xB9, 0x49, 0x01, 0x23, 0x9E, 0x46, 0xEC, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x17, 0xD0, 0x20, 0x1D, 0x02, 0x99, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xE7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x0D, 0xD0, 0x46, 0x20, 0x00, 0x5D, 0x11, 0x28, 0x09, 0xD0, 0xA0, 0x6D, 0x00, 0x28, 0x06, 0xD0, 0xAC, 0x34, 0x04, 0x98, 0x01, 0x30, 0x04, 0x90, 0x01, 0x3E, 0xC1, 0xD1, 0x07, 0xE0, 0x04, 0x98, 0x00, 0x06, 0x00, 0x0E ,
0xAC, 0x21, 0x41, 0x43, 0xA6, 0x48, 0x40, 0x18, 0x68, 0x60, 0xA6, 0x48, 0xAD, 0x30, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0xB5, 0xC2, 0x68, 0x90, 0x69, 0x02, 0x21, 0x01, 0x23, 0x9E, 0x46, 0xA2, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xA2, 0x48, 0x61, 0x30, 0x00, 0xBD, 0x01, 0x79, 0x0B, 0x29, 0x03, 0xD0, 0x89, 0x00, 0x9F, 0x4A, 0x51, 0x5A, 0x01, 0xE0, 0x01, 0x21, 0x49, 0x02, 0x41, 0x60, 0x9D, 0x48, 0x0D, 0x30, 0xF7, 0x46, 0x01, 0x1C, 0xFF, 0xFF, 0x68, 0x66, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x9C, 0x48, 0x02, 0x68, 0x9C, 0x48, 0x01, 0x2A, 0x01, 0xD1, 0x25, 0x30, 0xF7, 0x46, 0x9B, 0x4A, 0x12, 0x68, 0x4A, 0x60, 0x19, 0x30, 0xF7, 0x46, 0x00, 0x21, 0x41, 0x60, 0x99, 0x48, 0x98, 0x49, 0x08, 0x18, 0xF7, 0x46, 0x00, 0x21, 0x41, 0x60, 0x97, 0x48, 0xE7, 0x49, 0x08, 0x18, 0xF7, 0x46, 0xFF, 0xB5, 0x46, 0x69, 0x40, 0x68, 0x01, 0x90, 0x94, 0x49, 0x0A, 0x7C, 0x9A, 0x4F, 0x01, 0x2A, 0x63, 0xD0, 0x09, 0x7C, 0x03, 0x29 ,
0x60, 0xD0, 0x91, 0x4A, 0x92, 0x4B, 0x00, 0x21, 0x02, 0x91, 0x59, 0x56, 0x24, 0x23, 0x59, 0x43, 0x53, 0x18, 0x03, 0x93, 0x01, 0x28, 0x17, 0xD1, 0x8A, 0x18, 0x04, 0x23, 0x6C, 0x46, 0x8C, 0x49, 0x15, 0x79, 0x08, 0x78, 0xC0, 0x43, 0x28, 0x43, 0x20, 0x70, 0x01, 0x32, 0x01, 0x31, 0x01, 0x34, 0x01, 0x3B, 0xF5, 0xD1, 0x31, 0x1D, 0x68, 0x46, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xA9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x40, 0xD0, 0x35, 0x1D, 0x82, 0x48, 0x00, 0x78, 0xFF, 0x28, 0xFF, 0xFF, 0xFE, 0x66, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x11, 0xD0, 0x00, 0x28, 0x0F, 0xD0, 0x03, 0x98, 0x01, 0x1D, 0x28, 0x1C, 0x01, 0x24, 0xA6, 0x46, 0x7E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x00, 0x28, 0x05, 0xD1, 0x7A, 0x48, 0xA6, 0x46, 0x7B, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x05, 0xE0, 0x28, 0x1C, 0x01, 0x21, 0x8E, 0x46, 0x78, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x99, 0x01, 0x29, 0x01, 0xD1, 0x00, 0x28, 0x1E, 0xD1 ,
0x01, 0x99, 0x5F, 0x31, 0x01, 0xD0, 0x00, 0x28, 0x0F, 0xD1, 0xA8, 0x20, 0x81, 0x5D, 0x00, 0x29, 0x08, 0xD0, 0x49, 0x1E, 0x81, 0x55, 0x80, 0x5D, 0x00, 0x28, 0x09, 0xD1, 0x38, 0x1C, 0xFF, 0x30, 0x08, 0x30, 0x11, 0xE0, 0x03, 0x21, 0x02, 0x91, 0x00, 0xE0, 0xA8, 0x20, 0x02, 0x99, 0x81, 0x55, 0x38, 0x1C, 0xFF, 0x30, 0x16, 0x30, 0x07, 0xE0, 0x01, 0x98, 0x01, 0x28, 0x02, 0xD1, 0x38, 0x1C, 0xA3, 0x30, 0x01, 0xE0, 0x38, 0x1C, 0x9F, 0x30, 0x00, 0x90, 0xFF, 0xBD, 0x00, 0xB5, 0x02, 0x1C, 0x10, 0x6A, 0xD1, 0x69, 0x52, 0x69, 0xC3, 0x69, 0x5A, 0x60, 0xFF, 0xFF, 0x94, 0x67, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x01, 0x22, 0x96, 0x46, 0x5E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x5E, 0x48, 0xFF, 0x30, 0x6E, 0x30, 0x00, 0xBD, 0x10, 0xB5, 0x0A, 0x1C, 0x41, 0x69, 0x00, 0x6A, 0x93, 0x69, 0xDB, 0x69, 0x58, 0x60, 0x90, 0x69, 0x01, 0x24, 0xA6, 0x46, 0x56, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0xA6, 0x46, 0x56, 0x48, 0xFE, 0x44 ,
0x00, 0x47, 0x55, 0x48, 0xFF, 0x30, 0xB6, 0x30, 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x1C, 0x6E, 0x69, 0x53, 0x48, 0x02, 0x68, 0x5C, 0x21, 0x88, 0x5D, 0x04, 0x28, 0x15, 0xD1, 0x07, 0x20, 0x88, 0x55, 0x10, 0x0B, 0x11, 0xD2, 0x01, 0x24, 0xA6, 0x46, 0x4E, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x00, 0x28, 0x0A, 0xD0, 0x47, 0x21, 0x89, 0x57, 0xC1, 0x60, 0x11, 0x21, 0xC9, 0x02, 0x00, 0x22, 0x04, 0x23, 0xA6, 0x46, 0xE8, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x01, 0x20, 0x68, 0x60, 0x43, 0x48, 0xED, 0x49, 0x08, 0x18, 0x70, 0xBD, 0x70, 0xB5, 0x05, 0x1C, 0xAE, 0x69, 0x9C, 0x20, 0x80, 0x19, 0x4B, 0x21, 0x89, 0x00, 0x01, 0x24, 0xFF, 0xFF, 0x2A, 0x68, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA6, 0x46, 0xE8, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x5C, 0x21, 0x88, 0x5D, 0x07, 0x28, 0x01, 0xD1, 0x09, 0x20, 0x00, 0xE0, 0x05, 0x20, 0xAA, 0x69, 0x88, 0x54, 0x30, 0x1C, 0xA6, 0x46, 0xE9, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x68, 0x60, 0xE8, 0x48 ,
0x4D, 0x30, 0x70, 0xBD, 0xF0, 0xB5, 0x41, 0x68, 0x82, 0x68, 0x88, 0x23, 0x5E, 0x18, 0x37, 0x88, 0x0B, 0x6F, 0x00, 0x2B, 0x01, 0xD1, 0x00, 0x2F, 0x10, 0xD1, 0x06, 0x2F, 0x02, 0xDD, 0x00, 0x21, 0xC9, 0x43, 0x07, 0xE0, 0x33, 0x88, 0x9B, 0x00, 0xC9, 0x18, 0x0A, 0x67, 0x31, 0x88, 0x01, 0x31, 0x31, 0x80, 0x01, 0x21, 0x81, 0x60, 0xE1, 0x48, 0x1D, 0x30, 0xF0, 0xBD, 0x0B, 0x1C, 0x01, 0x24, 0x5D, 0x6F, 0x1D, 0x67, 0x04, 0x33, 0x01, 0x34, 0x06, 0x2C, 0xE1, 0xDA, 0xF8, 0xE7, 0x00, 0xB5, 0x00, 0x21, 0xC1, 0x60, 0xE9, 0x48, 0x01, 0x68, 0x10, 0x31, 0xE6, 0x48, 0x20, 0x22, 0x01, 0x23, 0x9E, 0x46, 0xE7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE5, 0x48, 0xFB, 0x30, 0x00, 0xBD, 0xFF, 0xFF, 0xC0, 0x68, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x14, 0x0D, 0x1B, 0x00, 0x54, 0x19, 0x1B, 0x00, 0x91, 0x1A, 0x01, 0x00, 0x4B, 0xAD, 0x03, 0x00, 0x61, 0x4E, 0x01, 0x00, 0x06, 0x32, 0x08, 0x00, 0x1F, 0x0B, 0x02, 0x00, 0x54, 0x3F ,
0x08, 0x00, 0x45, 0xC1, 0x00, 0x00, 0x84, 0x3C, 0x08, 0x00, 0x1B, 0x02, 0x00, 0x00, 0xED, 0x17, 0x00, 0x00, 0xF3, 0xC1, 0x01, 0x00, 0x34, 0x19, 0x1B, 0x00, 0x08, 0x19, 0x1B, 0x00, 0xA6, 0x44, 0x08, 0x00, 0x1C, 0x17, 0x1B, 0x00, 0x18, 0x17, 0x1B, 0x00, 0xCB, 0x67, 0x03, 0x00, 0x0D, 0x47, 0x02, 0x00, 0x39, 0x42, 0x03, 0x00, 0xBD, 0xE7, 0x02, 0x00, 0xB1, 0x40, 0x03, 0x00, 0xB9, 0xEA, 0x01, 0x00, 0x45, 0xDA, 0x00, 0x00, 0x24, 0x41, 0x08, 0x00, 0x71, 0xC0, 0x02, 0x00, 0xF0, 0xB5, 0x88, 0xB0, 0x06, 0x91, 0x07, 0x90, 0x86, 0x69, 0xF0, 0x1C, 0xD9, 0xA1, 0x04, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x14, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x32, 0xD1, 0xF2, 0x79, 0xD7, 0x48, 0x02, 0x70, 0x35, 0x7A, 0x77, 0x7A, 0x78, 0x1B, 0xFF, 0xFF, 0x56, 0x69, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x43, 0x1C, 0x93, 0x42, 0x1D, 0xD0, 0x16, 0x2A, 0x0C, 0xDB, 0x00, 0x2D, 0x0A, 0xD1, 0xD6, 0x48, 0x04, 0x70, 0x0A, 0x20 ,
0x81, 0x19, 0xD0, 0x48, 0x1A, 0x1C, 0xA6, 0x46, 0xB8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x74, 0xE0, 0xD2, 0x48, 0x04, 0x70, 0xCC, 0x48, 0x40, 0x19, 0x0A, 0x21, 0x89, 0x19, 0x7A, 0x1B, 0x52, 0x1C, 0xA6, 0x46, 0xB1, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x67, 0xE0, 0x8F, 0xC6, 0x03, 0x00, 0xC9, 0x48, 0x04, 0x70, 0xC9, 0x48, 0x04, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xC2, 0x48, 0xA6, 0x46, 0xAA, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x59, 0xE0, 0xF0, 0x1C, 0x03, 0x21, 0x0A, 0x1C, 0xBC, 0xA1, 0xA6, 0x46, 0xC6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x4F, 0xD1, 0xF1, 0x79, 0xBB, 0x48, 0x01, 0x70, 0xBB, 0x4D, 0xB2, 0x79, 0x2A, 0x70, 0x03, 0x20, 0x17, 0x49, 0xF4, 0x31, 0xA6, 0x46, 0xB8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x28, 0x78, 0x00, 0x28, 0x0B, 0xD1, 0xFF, 0xE7, 0xB8, 0x49, 0x0C, 0x70, 0xB8, 0x49, 0xFF, 0xFF, 0xEC, 0x69, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0C, 0x70, 0x03, 0x20, 0x0F, 0x49, 0xF5, 0x31, 0xA6, 0x46 ,
0xB6, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x20, 0x1C, 0xF2, 0x79, 0x35, 0x7A, 0x77, 0x7A, 0x79, 0x1B, 0x4B, 0x1C, 0x93, 0x42, 0x20, 0xD0, 0xA9, 0x49, 0x09, 0x78, 0x16, 0x29, 0x0F, 0xDB, 0x00, 0x2D, 0x0D, 0xD1, 0xAB, 0x49, 0x08, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xE9, 0x48, 0x1A, 0x1C, 0xA6, 0x46, 0x8B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x1A, 0xE0, 0xC0, 0x46, 0xC7, 0x04, 0x00, 0x00, 0xA5, 0x49, 0x08, 0x70, 0xE3, 0x48, 0x40, 0x19, 0x0A, 0x21, 0x89, 0x19, 0x7A, 0x1B, 0x52, 0x1C, 0xA6, 0x46, 0x83, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x0A, 0xE0, 0x9E, 0x49, 0x08, 0x70, 0x9E, 0x49, 0x08, 0x70, 0x0A, 0x20, 0x81, 0x19, 0xDB, 0x48, 0xA6, 0x46, 0x7D, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x96, 0x48, 0x00, 0x78, 0x00, 0x28, 0x0A, 0xD0, 0x95, 0x48, 0x00, 0x78, 0x00, 0x28, 0x06, 0xD0, 0x94, 0x48, 0x00, 0x78, 0x00, 0x28, 0x02, 0xD0, 0x93, 0x48, 0x00, 0x78, 0x00, 0x28, 0xFF, 0xFF, 0x82, 0x6A, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00 ,
0x00, 0xD1, 0x8C, 0xE0, 0x03, 0x20, 0x17, 0x21, 0x89, 0x01, 0xA6, 0x46, 0x90, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x87, 0x48, 0x01, 0x78, 0x87, 0x48, 0x07, 0x78, 0x84, 0x4E, 0x83, 0x4D, 0xE0, 0x48, 0x00, 0x68, 0x00, 0x28, 0x2E, 0xD1, 0x07, 0x98, 0x41, 0x61, 0x06, 0x62, 0xC6, 0x48, 0x06, 0x9A, 0x10, 0x64, 0x02, 0x2F, 0x01, 0xD0, 0x03, 0x2F, 0x01, 0xD1, 0x03, 0x22, 0x00, 0xE0, 0x3A, 0x1C, 0x06, 0x9B, 0xDA, 0x63, 0x2A, 0x78, 0x9A, 0x63, 0x01, 0x2F, 0x03, 0xD1, 0x05, 0x29, 0x04, 0xD0, 0x0D, 0x29, 0x02, 0xD0, 0xEC, 0x48, 0xDB, 0x30, 0x64, 0xE0, 0x00, 0x25, 0x00, 0x95, 0x01, 0x91, 0x02, 0x96, 0x03, 0x95, 0x04, 0x90, 0x2B, 0x1C, 0x20, 0x1C, 0x01, 0x1C, 0x8E, 0x46, 0xE6, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0xE6, 0x48, 0x04, 0x60, 0x28, 0x1C, 0xA6, 0x46, 0xE5, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x4C, 0xE0, 0x0D, 0x27, 0x00, 0x20, 0x39, 0x1C, 0x05, 0xAA, 0xA6, 0x46, 0xE3, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x68, 0x46 ,
0xFF, 0xFF, 0x18, 0x6B, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x80, 0x8A, 0x40, 0x08, 0x05, 0xD2, 0x38, 0x1C, 0x50, 0x21, 0xA6, 0x46, 0xDC, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x38, 0x1C, 0x21, 0x1C, 0x0B, 0x1C, 0x29, 0x1C, 0x00, 0x22, 0xA6, 0x46, 0xD9, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x2B, 0x78, 0x0D, 0x20, 0x31, 0x1C, 0x22, 0x1C, 0xA6, 0x46, 0xD5, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x28, 0x78, 0x01, 0x30, 0x02, 0x1C, 0x0D, 0x20, 0x57, 0x49, 0x23, 0x1C, 0xA6, 0x46, 0xD0, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x55, 0x4E, 0x28, 0x78, 0x02, 0x30, 0x02, 0x1C, 0x0D, 0x20, 0x31, 0x1C, 0x23, 0x1C, 0xA6, 0x46, 0xCA, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x30, 0x78, 0x00, 0x28, 0x0A, 0xD0, 0x28, 0x78, 0x03, 0x30, 0x02, 0x1C, 0x4C, 0x48, 0x03, 0x78, 0x0D, 0x20, 0x8F, 0x49, 0xA6, 0x46, 0xC3, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0xBF, 0x48, 0x04, 0x60, 0x00, 0x20, 0xA6, 0x46, 0xBE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xB9, 0x48, 0xEC, 0x49 ,
0x08, 0x18, 0x08, 0xB0, 0xF0, 0xBD, 0xC0, 0x46, 0x7B, 0xC0, 0xFF, 0xFF, 0xAE, 0x6B, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x1C, 0xE9, 0x48, 0x02, 0x68, 0xE9, 0x48, 0x00, 0x2A, 0x04, 0xD0, 0x00, 0x22, 0x0A, 0x62, 0x8A, 0x61, 0x1D, 0x30, 0xF7, 0x46, 0xD7, 0x30, 0xF7, 0x46, 0xC0, 0x46, 0x9F, 0x03, 0x00, 0x00, 0x7D, 0xB8, 0x03, 0x00, 0x01, 0x1C, 0xE2, 0x48, 0x02, 0x68, 0xE2, 0x48, 0x00, 0x2A, 0x02, 0xD0, 0xFF, 0x30, 0xB4, 0x30, 0xF7, 0x46, 0x00, 0x22, 0xCA, 0x61, 0x8A, 0x61, 0x4F, 0x30, 0xF7, 0x46, 0xC9, 0x21, 0x01, 0x00, 0x91, 0xE1, 0x00, 0x00, 0xDB, 0x48, 0x01, 0x68, 0x8A, 0x69, 0x01, 0x20, 0xC0, 0x03, 0x10, 0x43, 0x88, 0x61, 0x00, 0x20, 0x08, 0x61, 0xD8, 0x48, 0x23, 0x30, 0xF7, 0x46, 0x89, 0x17, 0x02, 0x00, 0x70, 0xB5, 0x05, 0x1C, 0xD5, 0x4E, 0x29, 0x6A, 0xEA, 0x69, 0x30, 0x1C, 0x01, 0x24, 0xA6, 0x46, 0x0B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x68, 0x69, 0xA6, 0x46, 0xD1, 0x49 ,
0xFE, 0x44, 0x08, 0x47, 0xA8, 0x69, 0x06, 0x30, 0xA8, 0x60, 0xCF, 0x48, 0x00, 0x68, 0x68, 0x60, 0xEE, 0x60, 0xCE, 0x48, 0xFF, 0xFF, 0x44, 0x6C, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x6D, 0x30, 0x70, 0xBD, 0x46, 0x17, 0x1B, 0x00, 0x30, 0x3F, 0x08, 0x00, 0x41, 0xEB, 0x00, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x30, 0xB5, 0xEE, 0x48, 0x01, 0x6D, 0x80, 0x6C, 0x08, 0x43, 0x18, 0xD0, 0xEC, 0x49, 0x08, 0x1C, 0x07, 0x22, 0xFF, 0x23, 0x09, 0x33, 0x1B, 0x58, 0x00, 0x2B, 0x04, 0xD0, 0xFF, 0x30, 0x1D, 0x30, 0x01, 0x3A, 0xF6, 0xD1, 0x0B, 0xE0, 0x02, 0x20, 0xF0, 0x4A, 0xF1, 0x4B, 0x01, 0x24, 0xA6, 0x46, 0xF0, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0xA6, 0x46, 0xEF, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xEF, 0x48, 0xFF, 0x30, 0x5C, 0x30, 0x30, 0xBD, 0xC0, 0x46, 0x53, 0x53, 0x49, 0x44, 0x00, 0xC0, 0x46, 0xC0, 0x4B, 0x45, 0x59, 0x00, 0xEE, 0x62, 0x08, 0x00, 0xF0, 0x62, 0x08, 0x00, 0xEC, 0x62, 0x08, 0x00, 0xED, 0x62, 0x08, 0x00 ,
0xE7, 0x7E, 0x03, 0x00, 0xE8, 0x62, 0x08, 0x00, 0xE9, 0x62, 0x08, 0x00, 0xEA, 0x62, 0x08, 0x00, 0xEB, 0x62, 0x08, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0xF0, 0xB5, 0xFF, 0xFF, 0xDA, 0x6C, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x87, 0xB0, 0x00, 0x91, 0x01, 0x90, 0x6B, 0x48, 0x01, 0x68, 0xCC, 0x4A, 0x14, 0x1C, 0x02, 0x94, 0x07, 0x26, 0x00, 0x25, 0x03, 0x95, 0x04, 0x94, 0x05, 0x95, 0xDF, 0x48, 0x00, 0x68, 0x08, 0x43, 0x27, 0xD0, 0xE0, 0x68, 0x03, 0x99, 0x88, 0x42, 0x0A, 0xDD, 0x03, 0x90, 0x40, 0x1C, 0x00, 0x99, 0x88, 0x60, 0xC2, 0x49, 0xFF, 0x20, 0x1D, 0x30, 0x68, 0x43, 0x0C, 0x18, 0xE0, 0x68, 0x04, 0x91, 0x02, 0x99, 0xC9, 0x68, 0x88, 0x42, 0x10, 0xDB, 0x88, 0x42, 0x10, 0xD1, 0x02, 0x98, 0x01, 0x27, 0xBE, 0x46, 0xCE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x06, 0x90, 0x20, 0x1C, 0xBE, 0x46, 0xCB, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x06, 0x99, 0x88, 0x42, 0x01, 0xDA, 0x05, 0x95, 0x02, 0x94 ,
0x51, 0x48, 0x01, 0x68, 0xFF, 0x27, 0x09, 0x37, 0x38, 0x59, 0x00, 0x28, 0x06, 0xD0, 0xC7, 0x48, 0x00, 0x68, 0x07, 0x2E, 0x00, 0xD1, 0x2E, 0x1C, 0x08, 0x43, 0x04, 0xD0, 0xFF, 0x34, 0x1D, 0x34, 0x01, 0x35, 0x07, 0x2D, 0xC2, 0xDB, 0x07, 0x2E, 0xFF, 0xFF, 0x70, 0x6D, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0A, 0xD1, 0xC0, 0x48, 0x00, 0x68, 0x08, 0x43, 0x06, 0xD0, 0x05, 0x9E, 0x30, 0x1C, 0x01, 0x21, 0x8E, 0x46, 0xBA, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x98, 0x47, 0x61, 0x00, 0x21, 0x81, 0x61, 0xFF, 0x22, 0x1D, 0x32, 0x72, 0x43, 0x04, 0x99, 0x89, 0x18, 0xC1, 0x61, 0x06, 0x62, 0xB4, 0x48, 0x39, 0x30, 0x07, 0xB0, 0xF0, 0xBD, 0x10, 0xB5, 0x04, 0x1C, 0x00, 0x20, 0x01, 0x21, 0x8E, 0x46, 0xB1, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x40, 0x1E, 0x00, 0xD5, 0x00, 0x20, 0x60, 0x60, 0xE0, 0x61, 0xAE, 0x48, 0x21, 0x30, 0x10, 0xBD, 0xC0, 0x46, 0x10, 0x63, 0x08, 0x00, 0x70, 0xB5, 0x04, 0x1C, 0xE5, 0x69, 0x66, 0x69 ,
0x00, 0x20, 0x01, 0x21, 0x8E, 0x46, 0xA7, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x60, 0x60, 0xAB, 0x19, 0xA6, 0x4A, 0xA5, 0x49, 0x93, 0x42, 0x02, 0xD3, 0x9A, 0x1A, 0x82, 0x42, 0x02, 0xD9, 0x08, 0x1C, 0x99, 0x30, 0x70, 0xBD, 0x08, 0x1C, 0xAB, 0x30, 0x70, 0xBD, 0x08, 0x6B, 0x41, 0x7D, 0x02, 0x88, 0x92, 0x00, 0xFF, 0xFF, 0x06, 0x6E, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x51, 0x1A, 0x3C, 0x39, 0xFF, 0x22, 0x5F, 0x32, 0x91, 0x42, 0x03, 0xD9, 0x65, 0x21, 0x01, 0x80, 0x02, 0x21, 0x81, 0x73, 0x9B, 0x48, 0x99, 0x49, 0x08, 0x18, 0xF7, 0x46, 0xC0, 0x46, 0x30, 0x63, 0x08, 0x00, 0xF8, 0xB5, 0x40, 0x68, 0x24, 0x21, 0x41, 0x43, 0x97, 0x48, 0x45, 0x18, 0x28, 0x1D, 0x0C, 0x21, 0x49, 0x19, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x94, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x91, 0x4C, 0x00, 0x28, 0x1B, 0xD0, 0x2B, 0x1C, 0x04, 0x22, 0x6E, 0x46, 0x91, 0x49, 0x1F, 0x7B, 0x08, 0x78, 0xC0, 0x43, 0x38, 0x43, 0x30, 0x70, 0x01, 0x33 ,
0x01, 0x31, 0x01, 0x36, 0x01, 0x3A, 0xF5, 0xD1, 0x0C, 0x20, 0x41, 0x19, 0x68, 0x46, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x87, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x02, 0xD0, 0x20, 0x1C, 0x4A, 0x30, 0xF8, 0xBD, 0x20, 0x1C, 0xF8, 0xBD, 0xB1, 0xBD, 0x00, 0x00, 0x15, 0x95, 0x00, 0x00, 0x58, 0x3F, 0x08, 0x00, 0xF3, 0xF8, 0x00, 0x00, 0xE9, 0x09, 0x02, 0x00, 0xFF, 0xFF, 0x9C, 0x6E, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x2B, 0x09, 0x02, 0x00, 0xDD, 0x0A, 0x02, 0x00, 0xF8, 0xB5, 0x05, 0x1C, 0xAA, 0x69, 0x7D, 0x49, 0x00, 0x20, 0x08, 0x56, 0x24, 0x21, 0x41, 0x43, 0x76, 0x48, 0x43, 0x18, 0x04, 0x24, 0x6E, 0x46, 0x76, 0x49, 0x1F, 0x79, 0x08, 0x78, 0xC0, 0x43, 0x38, 0x43, 0x30, 0x70, 0x01, 0x33, 0x01, 0x31, 0x01, 0x36, 0x01, 0x3C, 0xF5, 0xD1, 0x11, 0x1D, 0x68, 0x46, 0x04, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x6D, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x01, 0x1C, 0x6D, 0x48, 0x04, 0xD0, 0x6E, 0x49, 0x09, 0x78 ,
0x69, 0x60, 0x45, 0x30, 0xF8, 0xBD, 0xEC, 0x61, 0xAF, 0x30, 0xF8, 0xBD, 0x70, 0xB5, 0xC5, 0x68, 0x81, 0x68, 0x0A, 0x89, 0x6D, 0x4E, 0x00, 0x2A, 0x22, 0xD0, 0x01, 0x24, 0xC2, 0x6D, 0xA2, 0x18, 0xC2, 0x65, 0x08, 0x89, 0x0D, 0x28, 0x1B, 0xD1, 0x68, 0x6B, 0x21, 0x1C, 0xA6, 0x46, 0x63, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x22, 0x1C, 0x28, 0x1C, 0x00, 0x21, 0xA6, 0x46, 0x60, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x2C, 0x60, 0xE9, 0x6B, 0xFF, 0xFF, 0x32, 0x6F, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x28, 0x1C, 0xA6, 0x46, 0x5E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x28, 0x1C, 0xA6, 0x46, 0x5C, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x30, 0x1C, 0x3D, 0x30, 0x70, 0xBD, 0x30, 0x1C, 0x23, 0x30, 0x70, 0xBD, 0xC0, 0x46, 0xB1, 0x02, 0x00, 0x00, 0x74, 0x3F, 0x08, 0x00, 0x19, 0xC6, 0x00, 0x00, 0x5C, 0x3F, 0x08, 0x00, 0x1D, 0xC2, 0x00, 0x00, 0x68, 0x44, 0x08, 0x00, 0x43, 0x12, 0x03, 0x00, 0x34, 0x63, 0x08, 0x00, 0x2F, 0x7A, 0x02, 0x00 ,
0xB4, 0x36, 0x08, 0x00, 0x8F, 0xF4, 0x01, 0x00, 0xF0, 0xB5, 0x05, 0x1C, 0xAB, 0x69, 0xEC, 0x69, 0x60, 0x68, 0x00, 0x68, 0x2A, 0x30, 0x01, 0x78, 0x0A, 0x06, 0x41, 0x78, 0x09, 0x04, 0x8A, 0x18, 0x81, 0x78, 0x09, 0x02, 0x8A, 0x18, 0xC1, 0x78, 0x8A, 0x18, 0x8E, 0x26, 0xF1, 0x5A, 0x09, 0x0A, 0x01, 0x70, 0xF0, 0x5C, 0x61, 0x68, 0x09, 0x68, 0x2B, 0x26, 0x70, 0x54, 0x8C, 0x20, 0xC0, 0x18, 0x61, 0x68, 0x0E, 0x68, 0x01, 0x88, 0x09, 0x0A, 0x2C, 0x27, 0xB9, 0x55, 0x61, 0x68, 0x09, 0x68, 0xFF, 0xFF, 0xC8, 0x6F, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x2D, 0x26, 0x00, 0x78, 0x70, 0x54, 0x60, 0x68, 0x01, 0x68, 0x32, 0x31, 0x08, 0x78, 0x00, 0x02, 0x49, 0x78, 0x08, 0x18, 0x00, 0x04, 0x00, 0x0C, 0x8C, 0x21, 0xCB, 0x58, 0x35, 0x49, 0x41, 0x40, 0x08, 0x04, 0x00, 0x0C, 0xC0, 0x18, 0x80, 0x1A, 0x01, 0x21, 0x8E, 0x46, 0x32, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x61, 0x68, 0x0A, 0x68, 0x32, 0x23, 0x01, 0x0A, 0x99, 0x54 ,
0x61, 0x68, 0x09, 0x68, 0x33, 0x22, 0x50, 0x54, 0x60, 0x68, 0x68, 0x60, 0x2C, 0x48, 0xF0, 0xBD, 0x00, 0x00, 0x1B, 0x00, 0x34, 0x04, 0x1B, 0x00, 0x02, 0x6A, 0x8B, 0x69, 0xDB, 0x69, 0x1B, 0x68, 0x83, 0x60, 0x88, 0x69, 0xC0, 0x69, 0x41, 0x68, 0x8A, 0x42, 0x00, 0xDA, 0x42, 0x60, 0x25, 0x48, 0x79, 0x30, 0xF7, 0x46, 0x24, 0x48, 0x57, 0x30, 0xF7, 0x46, 0x24, 0x48, 0x91, 0x30, 0xF7, 0x46, 0x32, 0x04, 0x00, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x15, 0x09, 0x02, 0x00, 0xC5, 0x93, 0x00, 0x00, 0x0D, 0x91, 0x00, 0x00, 0x40, 0x1E, 0x80, 0x00, 0x1E, 0x4B, 0xFF, 0xFF, 0x5E, 0x70, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x19, 0x50, 0x1C, 0x49, 0x0A, 0x50, 0xF7, 0x46, 0xC0, 0x46, 0xBD, 0xB5, 0x00, 0x00, 0x95, 0x92, 0x00, 0x00, 0xFD, 0x93, 0x00, 0x00, 0x54, 0x3F, 0x08, 0x00, 0x29, 0x4F, 0x03, 0x00, 0xDF, 0xE8, 0x02, 0x00, 0x36, 0x89, 0x41, 0x00, 0x81, 0x06, 0x00, 0x00, 0xB1, 0x78, 0x00, 0x00, 0x94, 0xEC, 0x01, 0x00 ,
0x08, 0x19, 0x1B, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0x1C, 0x17, 0x1B, 0x00, 0x67, 0x66, 0x03, 0x00, 0xA6, 0x44, 0x08, 0x00, 0x18, 0x17, 0x1B, 0x00, 0xA7, 0x2F, 0x02, 0x00, 0x91, 0x44, 0x03, 0x00, 0x91, 0x63, 0x03, 0x00, 0x5B, 0x44, 0x03, 0x00, 0xE7, 0x44, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x61, 0xA2, 0x03, 0x00, 0x6A, 0x1E, 0x01, 0x00, 0x45, 0xDA, 0x00, 0x00, 0xD7, 0xE8, 0x01, 0x00, 0xE9, 0x78, 0x02, 0x00, 0x04, 0xF3, 0x1A, 0x00, 0x80, 0x7B, 0x08, 0x00, 0xFC, 0xB5, 0x04, 0x1C, 0xA5, 0x69, 0x60, 0x6A, 0x01, 0x90, 0x20, 0x69, 0x00, 0x28, 0x35, 0xD4, 0x08, 0x28, 0x33, 0xDA, 0xE1, 0x69, 0x09, 0x68, 0xFF, 0xFF, 0xF4, 0x70, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x10, 0x29, 0x2F, 0xD1, 0xAC, 0x21, 0x41, 0x43, 0x9E, 0x4A, 0x51, 0x5C, 0x49, 0x08, 0x27, 0xD3, 0x00, 0x06, 0x00, 0x16, 0xA2, 0x68, 0x69, 0x46, 0x01, 0x23, 0x9E, 0x46, 0x9A, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x06, 0x1C, 0x39, 0x30, 0x1F, 0xD0 ,
0x00, 0x2E, 0x1D, 0xD0, 0x00, 0x98, 0x07, 0x68, 0x00, 0x99, 0x0C, 0x39, 0x01, 0x98, 0x01, 0x60, 0x28, 0x1D, 0x10, 0x21, 0x79, 0x1A, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x91, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x22, 0x2A, 0x80, 0xA8, 0x1C, 0x08, 0x21, 0x79, 0x1A, 0x01, 0x23, 0x9E, 0x46, 0x8C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x03, 0xE0, 0x38, 0x20, 0x00, 0xE0, 0x00, 0x20, 0xC6, 0x43, 0x26, 0x60, 0x89, 0x48, 0x7C, 0x30, 0x20, 0x62, 0xFC, 0xBD, 0x30, 0xB5, 0x05, 0x1C, 0x28, 0x69, 0xA9, 0x69, 0x90, 0x29, 0x1D, 0xD1, 0x69, 0x69, 0x09, 0x78, 0x04, 0x29, 0x19, 0xD0, 0x05, 0x29, 0x17, 0xD0, 0x0A, 0x29, 0x15, 0xD0, 0x06, 0x29, 0x13, 0xD0, 0x0C, 0x29, 0x01, 0xDB, 0xFF, 0xFF, 0x8A, 0x71, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x10, 0x29, 0x0F, 0xD1, 0x01, 0x24, 0xA6, 0x46, 0x7D, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x7C, 0x48, 0x7D, 0x49, 0x00, 0x22, 0xA6, 0x46, 0x7C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x7C, 0x48 ,
0xFF, 0x30, 0x5F, 0x30, 0x28, 0x62, 0x30, 0xBD, 0xF0, 0xB5, 0x89, 0xB0, 0x05, 0x90, 0x41, 0x69, 0x02, 0x69, 0x75, 0x48, 0x79, 0x4E, 0x82, 0x42, 0x3A, 0xD0, 0x04, 0x30, 0x82, 0x42, 0x25, 0xD0, 0x74, 0x4D, 0xAA, 0x42, 0x00, 0xD0, 0xCC, 0xE0, 0x08, 0x68, 0x06, 0x1C, 0x0C, 0x22, 0x8F, 0x1A, 0x4A, 0x68, 0x89, 0x18, 0x09, 0x1D, 0x10, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x6E, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x01, 0x1C, 0x09, 0xD1, 0xAC, 0x22, 0x72, 0x43, 0xCB, 0x48, 0x80, 0x18, 0x46, 0x22, 0x12, 0x5C, 0x11, 0x2A, 0x01, 0xD1, 0x44, 0x22, 0x14, 0x54, 0x28, 0x1C, 0x3A, 0x1C, 0xA6, 0x46, 0x62, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x69, 0x48, 0xEC, 0x30, 0xAB, 0xE0, 0x08, 0x68, 0xC0, 0x00, 0x30, 0x18, 0x8A, 0x68, 0x02, 0x2A, 0x02, 0xD0, 0xFF, 0xFF, 0x20, 0x72, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xE7, 0x20, 0x80, 0x00, 0xA2, 0xE0, 0xCA, 0x68, 0x89, 0x18, 0x09, 0x7B, 0x41, 0x60, 0x80, 0x21, 0x01, 0x60, 0x3B, 0x20 ,
0x00, 0x01, 0x99, 0xE0, 0x08, 0x68, 0x06, 0x90, 0xC0, 0x00, 0x34, 0x58, 0x10, 0x20, 0x04, 0x90, 0x01, 0x25, 0xAE, 0x46, 0x57, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x07, 0x90, 0x00, 0x28, 0x00, 0xD1, 0x89, 0xE0, 0x0C, 0x21, 0x07, 0x98, 0x0F, 0x18, 0xB0, 0x49, 0xAC, 0x20, 0x06, 0x9A, 0x50, 0x43, 0x08, 0x18, 0x48, 0x22, 0x13, 0x5C, 0x5B, 0x06, 0x5B, 0x0E, 0x13, 0x54, 0x06, 0x9A, 0xD2, 0x00, 0xB6, 0x18, 0x71, 0x68, 0x00, 0x29, 0x47, 0xD1, 0x00, 0x2C, 0x01, 0xDD, 0x08, 0x2C, 0x21, 0xDB, 0x00, 0x22, 0x69, 0x46, 0x0A, 0x70, 0x01, 0x92, 0x0A, 0x81, 0x8A, 0x72, 0xCD, 0x72, 0x0D, 0x73, 0x4D, 0x73, 0x01, 0x88, 0x44, 0x48, 0x06, 0x23, 0xAE, 0x46, 0x44, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x04, 0x1C, 0x02, 0xDC, 0x00, 0x20, 0xC0, 0x43, 0x36, 0xE0, 0x34, 0x60, 0xAC, 0x20, 0x60, 0x43, 0x9A, 0x49, 0xFF, 0xFF, 0xB6, 0x72, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x09, 0x18, 0x5C, 0x22, 0x28, 0x1C, 0x50, 0x54, 0x48, 0x20 ,
0x42, 0x5C, 0x52, 0x06, 0x52, 0x0E, 0x42, 0x54, 0xAC, 0x20, 0x60, 0x43, 0x94, 0x49, 0x08, 0x18, 0x5C, 0x21, 0x09, 0x5C, 0x49, 0x1E, 0x02, 0x29, 0x16, 0xD9, 0x03, 0x39, 0x08, 0xD0, 0x00, 0x20, 0x30, 0x56, 0xAE, 0x46, 0xEA, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x80, 0x20, 0x30, 0x60, 0xDB, 0xE7, 0x08, 0x94, 0x80, 0x21, 0x31, 0x60, 0x48, 0x22, 0x13, 0x5C, 0x19, 0x43, 0x11, 0x54, 0xAE, 0x46, 0xE4, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x0A, 0xE0, 0x01, 0x20, 0xCE, 0xE7, 0x06, 0x98, 0x39, 0x1C, 0x04, 0xAA, 0xAE, 0x46, 0xE0, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x1C, 0x08, 0x90, 0x06, 0x98, 0x38, 0x60, 0x08, 0x98, 0x78, 0x60, 0x00, 0x28, 0x15, 0xD0, 0xAC, 0x20, 0x60, 0x43, 0x7C, 0x49, 0x09, 0x18, 0x48, 0x88, 0x02, 0x04, 0x02, 0x20, 0x10, 0x43, 0xB8, 0x60, 0x48, 0x68, 0x02, 0x0E, 0x01, 0x02, 0x09, 0x0E, 0x09, 0x02, 0x11, 0x43, 0x02, 0x04, 0x12, 0x0E, 0xFF, 0xFF, 0x4C, 0x73, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00 ,
0x12, 0x04, 0x0A, 0x43, 0x00, 0x06, 0x10, 0x43, 0xF8, 0x60, 0x07, 0x98, 0x0D, 0x49, 0x00, 0x22, 0x10, 0x23, 0xAE, 0x46, 0xCE, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x13, 0x48, 0x00, 0xE0, 0x16, 0x20, 0xCC, 0x49, 0x09, 0x18, 0x05, 0x98, 0x01, 0x62, 0x09, 0xB0, 0xF0, 0xBD, 0x5D, 0x0D, 0x1B, 0x00, 0x81, 0xE7, 0x02, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x27, 0x1A, 0x02, 0x00, 0x2F, 0x7A, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0xCF, 0xF6, 0x00, 0x00, 0xD5, 0xF4, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x91, 0x19, 0x02, 0x00, 0x50, 0x65, 0x08, 0x00, 0x71, 0xC0, 0x02, 0x00, 0x50, 0x19, 0x1B, 0x00, 0x29, 0x16, 0x01, 0x00, 0x2A, 0x03, 0x00, 0x00, 0xF0, 0xB5, 0x8B, 0xB0, 0x07, 0x90, 0x05, 0x69, 0x47, 0x69, 0x0C, 0x20, 0x38, 0x1A, 0x08, 0x90, 0xB6, 0x49, 0x8D, 0x42, 0x16, 0xD1, 0x78, 0x68, 0x0F, 0x30, 0x00, 0x11, 0x00, 0x01, 0x78, 0x60, 0x38, 0x68, 0x0B, 0x28, 0x0E, 0xD8, 0x00, 0x23, 0x68, 0x46 ,
0xFF, 0xFF, 0xE2, 0x73, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x03, 0x70, 0x08, 0x98, 0x05, 0x22, 0x01, 0x24, 0xA6, 0x46, 0xAE, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0xAE, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0x08, 0x62, 0xAC, 0x48, 0x85, 0x42, 0x23, 0xD1, 0xAC, 0x48, 0x02, 0x78, 0x6C, 0x46, 0x22, 0x72, 0x43, 0x78, 0x63, 0x72, 0x81, 0x78, 0xA1, 0x72, 0xC0, 0x78, 0xE0, 0x72, 0x00, 0x91, 0x01, 0x90, 0x03, 0x20, 0xA6, 0x49, 0x01, 0x39, 0x01, 0x26, 0xB6, 0x46, 0xF3, 0x4E, 0xFE, 0x44, 0x30, 0x47, 0x04, 0x20, 0x20, 0x70, 0x08, 0x98, 0x9F, 0x49, 0x00, 0x22, 0x02, 0xAB, 0x01, 0x24, 0xA6, 0x46, 0x9B, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x9A, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0x08, 0x62, 0xEB, 0x49, 0x8D, 0x42, 0x14, 0xD1, 0x02, 0x22, 0x68, 0x46, 0x02, 0x70, 0x3A, 0x68, 0xAC, 0x20, 0x42, 0x43, 0x30, 0x48, 0x68, 0x30, 0x83, 0x18, 0x08, 0x98, 0x00, 0x22, 0x01, 0x24, 0xA6, 0x46, 0x8F, 0x4C, 0xFE, 0x44 ,
0x20, 0x47, 0x8E, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x07, 0x99, 0xFF, 0xFF, 0x78, 0x74, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x08, 0x62, 0xEF, 0x48, 0x85, 0x42, 0x00, 0xD0, 0x04, 0xE1, 0x03, 0x20, 0x8C, 0x49, 0x01, 0x22, 0x96, 0x46, 0xEC, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x86, 0x48, 0xFF, 0x30, 0x95, 0x30, 0x09, 0x90, 0x38, 0x68, 0xEA, 0x4D, 0x00, 0x28, 0x00, 0xD1, 0xE2, 0xE0, 0x01, 0x24, 0xA6, 0x46, 0xE6, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x00, 0x28, 0x00, 0xD1, 0xD6, 0xE0, 0xE4, 0x48, 0x02, 0x68, 0x03, 0x20, 0x7F, 0x49, 0x01, 0x31, 0xA6, 0x46, 0xE2, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xDF, 0x48, 0x00, 0x68, 0x00, 0x28, 0x5A, 0xD1, 0xDF, 0x4D, 0x2E, 0x20, 0x41, 0x19, 0xB8, 0x68, 0x03, 0x30, 0x08, 0x70, 0x38, 0x7A, 0x48, 0x70, 0x2E, 0x1C, 0x30, 0x36, 0xB8, 0x68, 0x28, 0x18, 0x30, 0x30, 0xDA, 0x49, 0x0A, 0x68, 0x30, 0x3A, 0x31, 0x1C, 0xA6, 0x46, 0xD8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x78, 0x68, 0x38, 0x18 ,
0x01, 0x1D, 0xBA, 0x68, 0x30, 0x1C, 0xA6, 0x46, 0xD9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xB8, 0x68, 0x41, 0x19, 0x97, 0x22, 0xFF, 0xFF, 0x0E, 0x75, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x09, 0x30, 0x50, 0x54, 0xB8, 0x68, 0x46, 0x19, 0x9E, 0x36, 0x30, 0x70, 0x01, 0x36, 0xB8, 0x68, 0x01, 0xE0, 0x14, 0x0D, 0x1B, 0x00, 0x30, 0x18, 0xCA, 0x49, 0x0A, 0x68, 0x9E, 0x3A, 0x31, 0x1C, 0xA6, 0x46, 0xC8, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x78, 0x68, 0x38, 0x18, 0x01, 0x1D, 0xBA, 0x68, 0x30, 0x1C, 0xA6, 0x46, 0xC9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xB8, 0x68, 0x40, 0x00, 0xC0, 0x49, 0x09, 0x68, 0x08, 0x18, 0x28, 0x18, 0xC0, 0x49, 0x0A, 0x79, 0x02, 0x70, 0x4A, 0x79, 0x42, 0x70, 0x8A, 0x79, 0x82, 0x70, 0xC9, 0x79, 0xC1, 0x70, 0x04, 0x30, 0x0F, 0x21, 0x41, 0x1A, 0x0A, 0x78, 0xBB, 0x68, 0x9A, 0x18, 0x0A, 0x70, 0x40, 0x1B, 0x00, 0x04, 0x00, 0x0C, 0xB5, 0x49, 0x08, 0x60, 0xB1, 0x48, 0x04, 0x60, 0x02, 0x20, 0x01, 0x1C ,
0x11, 0x22, 0xA6, 0x46, 0xB4, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x06, 0x1C, 0x63, 0xD4, 0x03, 0x20, 0xA6, 0x46, 0xB1, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x0A, 0x90, 0x00, 0x25, 0x01, 0x1C, 0xFF, 0xFF, 0xA4, 0x75, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x8D, 0x42, 0x50, 0xD0, 0x29, 0x1C, 0x2B, 0x22, 0xA6, 0x46, 0xAD, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x0C, 0x20, 0x0A, 0x99, 0x40, 0x18, 0xAC, 0x22, 0x72, 0x43, 0xAB, 0x49, 0x8F, 0x18, 0x78, 0x63, 0x29, 0x1C, 0x18, 0x22, 0xA6, 0x46, 0xA6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x9F, 0x48, 0x02, 0x68, 0x79, 0x6B, 0x4A, 0x60, 0x0A, 0x98, 0xAC, 0x30, 0x08, 0x60, 0x08, 0x68, 0x9A, 0x49, 0xA6, 0x46, 0xA0, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x29, 0x1C, 0x03, 0xA8, 0x10, 0x22, 0xA6, 0x46, 0x9C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE0, 0x21, 0x68, 0x46, 0x01, 0x74, 0x45, 0x74, 0x85, 0x74, 0xFB, 0x21, 0xC1, 0x74, 0xEE, 0x49, 0xC1, 0x81, 0x02, 0x21, 0x81, 0x81, 0x79, 0x6B, 0xCA, 0x68 ,
0x01, 0x20, 0xC0, 0x03, 0x10, 0x43, 0xC8, 0x60, 0x48, 0x68, 0x00, 0x90, 0x2A, 0x1C, 0x30, 0x1C, 0x0A, 0x9D, 0x29, 0x1C, 0x03, 0xAB, 0xA6, 0x46, 0xE6, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x07, 0x1C, 0x30, 0x06, 0x00, 0x16, 0xA6, 0x46, 0xEF, 0x49, 0xFF, 0xFF, 0x3A, 0x76, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xFE, 0x44, 0x08, 0x47, 0x28, 0x1C, 0xA6, 0x46, 0xEE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x11, 0xE0, 0x30, 0x06, 0x00, 0x16, 0xA6, 0x46, 0xE9, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x01, 0x20, 0xC7, 0x43, 0x08, 0xE0, 0x07, 0x1C, 0x06, 0xE0, 0x00, 0x20, 0x00, 0x21, 0xCF, 0x43, 0x01, 0xE0, 0x00, 0x20, 0x07, 0x1C, 0x28, 0x60, 0x00, 0x23, 0x68, 0x46, 0x03, 0x70, 0x3A, 0x06, 0x12, 0x0E, 0x08, 0x98, 0x6F, 0x49, 0x01, 0x24, 0xA6, 0x46, 0x09, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x07, 0x98, 0x09, 0x99, 0x01, 0x62, 0x0B, 0xB0, 0xF0, 0xBD, 0xC1, 0x18, 0x01, 0x00, 0xF1, 0x1B, 0x01, 0x00, 0xF3, 0x1C, 0x02, 0x00, 0x7B, 0xC0 ,
0x02, 0x00, 0x91, 0xF0, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0xA3, 0xC0, 0x02, 0x00, 0xA9, 0xE9, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00, 0xE4, 0x62, 0x08, 0x00, 0xAC, 0x05, 0x00, 0x00, 0xFE, 0xB5, 0x07, 0x1C, 0x7D, 0x69, 0xBE, 0x69, 0x0C, 0x20, 0x30, 0x1A, 0x01, 0x90, 0xDF, 0x4C, 0x0A, 0x2D, 0x13, 0xD1, 0xFF, 0xFF, 0xD0, 0x76, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x30, 0x68, 0xDB, 0x49, 0x08, 0x60, 0x01, 0x20, 0x86, 0x46, 0xDA, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x0A, 0x20, 0x00, 0x21, 0x01, 0x9A, 0x01, 0x23, 0x9E, 0x46, 0xE6, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xF5, 0x20, 0x80, 0x00, 0x00, 0x19, 0x38, 0x62, 0x03, 0x2D, 0x79, 0xD1, 0xF5, 0x20, 0x80, 0x00, 0x00, 0x19, 0x02, 0x90, 0x70, 0x68, 0x00, 0x28, 0x0C, 0xD1, 0x00, 0x21, 0xCF, 0x48, 0x01, 0x60, 0xCF, 0x48, 0x00, 0x68, 0x00, 0x28, 0x61, 0xD0, 0x01, 0x21, 0x8E, 0x46, 0xCD, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x5B, 0xE0, 0xCC, 0x48, 0xB1, 0x68, 0x01, 0x60 ,
0xF1, 0x68, 0x41, 0x60, 0x31, 0x69, 0x81, 0x60, 0x71, 0x69, 0xC1, 0x60, 0xB1, 0x69, 0xC1, 0x63, 0xF1, 0x69, 0x01, 0x64, 0x31, 0x6A, 0xC1, 0x64, 0x01, 0x24, 0xA6, 0x46, 0xC5, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xA6, 0x46, 0xC4, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x70, 0x68, 0x7D, 0x25, 0xED, 0x00, 0xA8, 0x42, 0x21, 0xD8, 0x01, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x05, 0xD0, 0xFF, 0xFF, 0x66, 0x77, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x28, 0x1C, 0xA6, 0x46, 0xBE, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x1C, 0xE0, 0xB9, 0x48, 0x00, 0x23, 0x19, 0x1C, 0x59, 0x43, 0x3E, 0x22, 0x4A, 0x43, 0x82, 0x83, 0x02, 0x30, 0x01, 0x33, 0x10, 0x2B, 0xF6, 0xDB, 0xA6, 0x46, 0xB4, 0x48, 0xFE, 0x44, 0x00, 0x47, 0xB5, 0x48, 0x0D, 0xE0, 0xB5, 0x4D, 0x28, 0x1C, 0xA6, 0x46, 0xB2, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x04, 0xE0, 0xA6, 0x46, 0xAF, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x75, 0x68, 0xAE, 0x48, 0x05, 0x60, 0x05, 0x1C, 0xA7, 0x4E, 0x30, 0x68 ,
0x00, 0x28, 0x06, 0xD1, 0xAD, 0x48, 0x00, 0x68, 0xA6, 0x46, 0xAC, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x30, 0x60, 0x00, 0x94, 0x2B, 0x68, 0xAA, 0x49, 0xAB, 0x4A, 0xA6, 0x46, 0xAB, 0x4D, 0xFE, 0x44, 0x28, 0x47, 0x9C, 0x48, 0x04, 0x60, 0x03, 0x20, 0x00, 0x21, 0x01, 0x9A, 0x01, 0x23, 0x9E, 0x46, 0xA7, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x98, 0x38, 0x62, 0xFE, 0xBD, 0xC0, 0x46, 0x13, 0x7F, 0x03, 0x00, 0x12, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x77, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x30, 0xB5, 0x05, 0x1C, 0x00, 0x20, 0x01, 0x24, 0xA6, 0x46, 0xA0, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xA6, 0x46, 0x9F, 0x49, 0xFE, 0x44, 0x08, 0x47, 0xA6, 0x46, 0x9E, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x7D, 0x21, 0xC9, 0x00, 0xA6, 0x46, 0x9E, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0x9B, 0x49, 0x08, 0x18, 0x99, 0x49, 0x08, 0x80, 0x9B, 0x48, 0x0A, 0x30, 0x28, 0x62, 0x30, 0xBD, 0x11, 0x10, 0x00, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0xB9, 0x90 ,
0x00, 0x00, 0x6C, 0x64, 0x08, 0x00, 0xE7, 0x7E, 0x03, 0x00, 0x74, 0x64, 0x08, 0x00, 0x70, 0x64, 0x08, 0x00, 0x6D, 0xC6, 0x03, 0x00, 0x08, 0x19, 0x1B, 0x00, 0x11, 0x18, 0x02, 0x00, 0xD1, 0x78, 0x02, 0x00, 0xC9, 0xBA, 0x03, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x14, 0x0D, 0x1B, 0x00, 0xFE, 0xB5, 0x02, 0x90, 0x45, 0x69, 0x68, 0x46, 0x01, 0x21, 0x8E, 0x46, 0x89, 0x49, 0xFE, 0x44, 0x08, 0x47, 0x89, 0x48, 0x04, 0x1C, 0x68, 0x68, 0x01, 0x69, 0x4A, 0x78, 0x00, 0x27, 0x3E, 0x1C, 0x20, 0x88, 0xFF, 0xFF, 0x92, 0x78, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x40, 0x08, 0x22, 0xD3, 0x20, 0x1D, 0x89, 0x1C, 0x01, 0x23, 0x9E, 0x46, 0x83, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x00, 0x28, 0x07, 0xD1, 0x68, 0x68, 0x00, 0x69, 0x40, 0x78, 0x21, 0x88, 0x09, 0x04, 0x89, 0x16, 0x81, 0x42, 0x3D, 0xD0, 0x02, 0x20, 0x00, 0x5F, 0x00, 0x99, 0x08, 0x1A, 0x00, 0x04, 0x00, 0x14, 0x3C, 0x28, 0x03, 0xDD, 0x20, 0x88, 0x40, 0x10, 0x40, 0x00 ,
0x20, 0x80, 0x78, 0x1C, 0x07, 0x06, 0x3F, 0x0E, 0x68, 0x68, 0x01, 0x69, 0x4A, 0x78, 0x2A, 0x34, 0x01, 0x36, 0x14, 0x2E, 0xD5, 0xDB, 0x00, 0x2A, 0x02, 0xD1, 0xAB, 0x20, 0x40, 0x00, 0x50, 0xE0, 0x00, 0x9B, 0x6D, 0x48, 0x14, 0x21, 0x00, 0x22, 0x04, 0x88, 0x64, 0x08, 0x03, 0xD3, 0x2A, 0x30, 0x01, 0x32, 0x01, 0x39, 0xF8, 0xD1, 0x12, 0x06, 0x12, 0x0E, 0x14, 0x2F, 0x16, 0xD1, 0x66, 0x48, 0x00, 0x88, 0x00, 0x06, 0x44, 0x16, 0x64, 0x49, 0x00, 0x22, 0x01, 0x20, 0x4E, 0x8D, 0x36, 0x06, 0x76, 0x16, 0xA6, 0x42, 0x02, 0xDD, 0x34, 0x1C, 0x02, 0x06, 0xFF, 0xFF, 0x28, 0x79, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0x12, 0x0E, 0x2A, 0x31, 0x01, 0x30, 0x14, 0x28, 0xF3, 0xDB, 0x02, 0xE0, 0x32, 0x06, 0x12, 0x0E, 0x00, 0x9B, 0x2A, 0x20, 0x42, 0x43, 0x5A, 0x48, 0x11, 0x18, 0x0C, 0x88, 0x01, 0x20, 0x20, 0x43, 0x00, 0x04, 0x00, 0x0C, 0x08, 0x80, 0xFE, 0x24, 0xA0, 0x43, 0x14, 0x24, 0x64, 0x57, 0x64, 0x06, 0x24, 0x0E ,
0x04, 0x43, 0x52, 0x48, 0x14, 0x52, 0x14, 0x18, 0x63, 0x80, 0x08, 0x88, 0x80, 0x05, 0x82, 0x0D, 0x68, 0x68, 0x00, 0x69, 0x40, 0x78, 0x80, 0x02, 0x10, 0x43, 0x08, 0x80, 0x68, 0x68, 0x02, 0x69, 0x20, 0x1D, 0x91, 0x1C, 0x52, 0x78, 0x01, 0x23, 0x9E, 0x46, 0x4B, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x02, 0x98, 0x04, 0x61, 0xFE, 0x20, 0x47, 0x49, 0x09, 0x18, 0x02, 0x98, 0x01, 0x62, 0xFE, 0xBD, 0x82, 0x69, 0x41, 0x69, 0x03, 0x69, 0x02, 0x2B, 0x0A, 0xD1, 0x01, 0x2A, 0x01, 0xD1, 0x00, 0x29, 0x05, 0xD0, 0x02, 0x2A, 0x04, 0xD1, 0x00, 0x29, 0x02, 0xD1, 0x11, 0x21, 0x00, 0xE0, 0x06, 0x21, 0x41, 0x61, 0xF7, 0x46, 0xFF, 0xFF, 0xBE, 0x79, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xC0, 0x46, 0x14, 0xE9, 0x00, 0x00, 0xC9, 0x18, 0x02, 0x00, 0x30, 0xB5, 0x05, 0x1C, 0x3A, 0x48, 0x00, 0x78, 0x00, 0x28, 0x04, 0xD0, 0x01, 0x20, 0x86, 0x46, 0x38, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x01, 0x24, 0xA6, 0x46, 0x37, 0x48, 0xFE, 0x44 ,
0x00, 0x47, 0xA6, 0x46, 0x36, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x35, 0x48, 0x0E, 0x30, 0x28, 0x62, 0x30, 0xBD, 0x49, 0x19, 0x01, 0x00, 0x2F, 0x7A, 0x02, 0x00, 0x18, 0xB5, 0x43, 0x69, 0x81, 0x69, 0x31, 0x48, 0x81, 0x29, 0x00, 0xD1, 0x0B, 0x38, 0x00, 0x21, 0x00, 0x91, 0x1A, 0x68, 0x9B, 0x68, 0x01, 0x24, 0xA6, 0x46, 0x2D, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x18, 0xBD, 0x18, 0xB5, 0x40, 0x69, 0x00, 0x21, 0x00, 0x91, 0x02, 0x68, 0x83, 0x68, 0x27, 0x48, 0x01, 0x30, 0x01, 0x24, 0xA6, 0x46, 0x26, 0x4C, 0xFE, 0x44, 0x20, 0x47, 0x18, 0xBD, 0xC0, 0x46, 0x30, 0x63, 0x08, 0x00, 0x19, 0x9E, 0x00, 0x00, 0xB9, 0xEC, 0x00, 0x00, 0x74, 0x3F, 0x08, 0x00, 0x80, 0x3F, 0x08, 0x00, 0xFF, 0xFF, 0x54, 0x7A, 0x08, 0x00, 0x96, 0x00, 0x00, 0x00, 0xB7, 0x5D, 0x03, 0x00, 0x00, 0x00, 0x1B, 0x00, 0xD3, 0x8E, 0x00, 0x00, 0xF7, 0xC6, 0x00, 0x00, 0xE5, 0x90, 0x00, 0x00, 0x68, 0x64, 0x08, 0x00, 0xC0, 0x27, 0x09, 0x00, 0xA0, 0x3B ,
0x08, 0x00, 0x3D, 0x5D, 0x03, 0x00, 0x19, 0xC6, 0x00, 0x00, 0xE8, 0x3A, 0x08, 0x00, 0x81, 0x5D, 0x03, 0x00, 0xCF, 0xF6, 0x00, 0x00, 0x4B, 0x4F, 0x03, 0x00, 0x6B, 0xC0, 0x03, 0x00, 0x95, 0x1E, 0x01, 0x00, 0xDA, 0x40, 0x08, 0x00, 0xDC, 0x05, 0x00, 0x00, 0x55, 0xAA, 0x03, 0x00, 0x0D, 0x91, 0x00, 0x00, 0xD7, 0x56, 0x03, 0x00, 0x08, 0x51, 0x08, 0x00, 0x8F, 0xC6, 0x03, 0x00, 0x65, 0xB8, 0x00, 0x00, 0x09, 0xB4, 0x03, 0x00, 0x84, 0x17, 0x1B, 0x00, 0xB5, 0x86, 0x01, 0x00, 0x3D, 0x47, 0x02, 0x00, 0x73, 0x49, 0x02, 0x00, 0x5F, 0x90, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x00, 0xF7, 0xF6, 0x00, 0x00, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x76, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x5A, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0xFF, 0xFF, 0xEA, 0x7A, 0x08, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x46, 0xFF, 0xF7, 0x99, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x83, 0xFF, 0xFF, 0xBD, 0xFF, 0xB5 ,
0x68, 0x46, 0xFF, 0xF7, 0xB6, 0xFE, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x55, 0xFC, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x27, 0xFB, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0xDD, 0xFA, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x68, 0xFE, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0x3D, 0xFB, 0xFF, 0xBD, 0xFF, 0xB5, 0x68, 0x46, 0xFF, 0xF7, 0xBE, 0xFD, 0xFF, 0xBD, 0x78, 0x7B, 0x08, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0xB5, 0xF8, 0xF0, 0x43, 0xFA, 0x00, 0xBD, 0x35, 0x66, 0x08, 0x00, 0x67, 0x66, 0x08, 0x00, 0x71, 0x65, 0x08, 0x00, 0x4D, 0x66, 0x08, 0x00, 0x25, 0x64, 0x08, 0x00, 0x81, 0x66, 0x08, 0x00, 0x8D, 0x66, 0x08, 0x00, 0x99, 0x66, 0x08, 0x00, 0x87, 0x67, 0x08, 0x00, 0xA7, 0x67, 0x08, 0x00, 0xD1, 0x67, 0x08, 0x00, 0x1B, 0x68, 0x08, 0x00, 0x57, 0x68, 0x08, 0x00, 0x2D, 0x69, 0x08, 0x00, 0xB1, 0x6B, 0x08, 0x00, 0xD5, 0x6B, 0x08, 0x00, 0xF9, 0x6B ,
0x08, 0x00, 0x15, 0x6C, 0x08, 0x00, 0xA1, 0x68, 0x08, 0x00, 0x59, 0x6C, 0x08, 0x00, 0xA7, 0x6D, 0x08, 0x00, 0xFF, 0x6D, 0x08, 0x00, 0x29, 0x6E, 0x08, 0x00, 0xF9, 0x6E, 0x08, 0x00, 0xD9, 0x6C, 0x08, 0x00, 0xA5, 0x6E, 0x08, 0x00, 0xCD, 0x6D, 0x08, 0x00, 0x81, 0x6F, 0x08, 0x00, 0x1D, 0x70, 0x08, 0x00, 0x31, 0x64, 0x08, 0x00, 0x39, 0x70, 0x08, 0x00, 0x3F, 0x70, 0x08, 0x00, 0x04, 0xF3, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x00, 0xB2, 0x4E, 0x01, 0x00, 0x5A, 0xC1, 0x00, 0x00, 0x96, 0x1A, 0x01, 0x00, 0x22, 0x0B, 0x02, 0x00, 0x60, 0xD0, 0x01, 0x00, 0x06, 0x1A, 0x00, 0x00, 0xB8, 0xC6, 0x01, 0x00, 0xD8, 0x42, 0x03, 0x00, 0x16, 0x42, 0x03, 0x00, 0xEE, 0xDB, 0x00, 0x00, 0x62, 0xDC, 0x00, 0x00, 0xC8, 0xE1, 0x00, 0x00, 0x8A, 0x17, 0x02, 0x00, 0x38, 0xBE, 0x00, 0x00, 0x26, 0xC6, 0x00, 0x00, 0x56, 0xC2, 0x00, 0x00, 0x62, 0x12, 0x03, 0x00, 0xE4, 0xF4, 0x01, 0x00, 0x3A, 0xEC, 0x00, 0x00, 0x5E, 0x92, 0x00, 0x00 ,
0xFE, 0xE8, 0x02, 0x00, 0x18, 0x7F, 0x00, 0x00, 0x64, 0xEC, 0x01, 0x00, 0xFE, 0x44, 0x03, 0x00, 0x1C, 0x94, 0x00, 0x00, 0xA8, 0x66, 0x03, 0x00, 0x74, 0xE9, 0x02, 0x00, 0x68, 0x1E, 0x01, 0x00, 0xBC, 0xDA, 0x00, 0x00, 0xEA, 0xE1, 0x00, 0x00, 0x24, 0xE9, 0x01, 0x00, 0x70, 0x79, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x1C, 0xF0, 0xB5, 0x88, 0xB0, 0xCA, 0x4C, 0x03, 0x20, 0x22, 0x78, 0x63, 0x78, 0xCA, 0x4E, 0x31, 0x1C, 0x01, 0x39, 0x01, 0x25, 0xAE, 0x46, 0xC7, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0xA2, 0x78, 0xE3, 0x78, 0x03, 0x20, 0x31, 0x1C, 0xAE, 0x46, 0xC3, 0x4F, 0xFE, 0x44, 0x38, 0x47, 0x03, 0x20, 0x31, 0x1C, 0x01, 0x31, 0xAE, 0x46, 0xC1, 0x4A, 0xFE, 0x44, 0x10, 0x47, 0xC1, 0x48, 0x21, 0x78, 0x01, 0x70, 0x61, 0x78, 0x41, 0x70, 0xE1, 0x78, 0xC1, 0x70, 0xA1, 0x78, 0x81, 0x70, 0xBF, 0x48, 0x04, 0x1C, 0x33, 0x3C, 0x20, 0x1C, 0x00, 0x21, 0xDC, 0x22, 0xAE, 0x46 ,
0xBA, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x84, 0x20, 0xA0, 0x70, 0x05, 0x27, 0xE7, 0x71, 0x0C, 0x26, 0x26, 0x73, 0x0D, 0x20, 0x00, 0x19, 0x98, 0xA1, 0x32, 0x1C, 0xAE, 0x46, 0xB4, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x20, 0x60, 0x76, 0x1A, 0x20, 0x00, 0x19, 0x97, 0xA1, 0x06, 0x91, 0x04, 0x22, 0xAE, 0x46, 0xAE, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xFF, 0xFF, 0x96, 0x00, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA7, 0x77, 0x1F, 0x34, 0x95, 0xA1, 0x07, 0x91, 0x20, 0x1C, 0x3A, 0x1C, 0xAE, 0x46, 0xA9, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE6, 0x71, 0x28, 0x1C, 0x60, 0x72, 0x11, 0x20, 0x20, 0x73, 0x94, 0x20, 0x60, 0x73, 0xC0, 0x25, 0x65, 0x74, 0xA6, 0x74, 0x09, 0x22, 0xE2, 0x74, 0xA3, 0x4C, 0x20, 0x1C, 0x8C, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x9F, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x07, 0x22, 0x62, 0x72, 0x9E, 0x4C, 0x0A, 0x34, 0x20, 0x1C, 0x89, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x9A, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x04, 0x20 ,
0xE0, 0x71, 0x98, 0x4C, 0x12, 0x34, 0x20, 0x1C, 0x06, 0x99, 0x04, 0x22, 0x01, 0x23, 0x9E, 0x46, 0x94, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x27, 0x71, 0x93, 0x4C, 0x17, 0x34, 0x20, 0x1C, 0x07, 0x99, 0x3A, 0x1C, 0x01, 0x23, 0x9E, 0x46, 0x8E, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0xE6, 0x71, 0x01, 0x20, 0x60, 0x72, 0x11, 0x20, 0x20, 0x73, 0x94, 0x20, 0x60, 0x73, 0x02, 0x20, 0xE0, 0x73, 0x25, 0x74, 0x66, 0x74, 0xFF, 0xFF, 0x2C, 0x01, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0xA5, 0x74, 0x2F, 0x27, 0xE7, 0x74, 0x10, 0x20, 0x60, 0x75, 0x80, 0x26, 0xA6, 0x75, 0x01, 0x20, 0xE0, 0x75, 0x11, 0x20, 0xA0, 0x76, 0x94, 0x20, 0xE0, 0x76, 0x24, 0x20, 0x60, 0x77, 0x0A, 0x22, 0xA2, 0x77, 0x80, 0x4C, 0x36, 0x34, 0x20, 0x1C, 0x6D, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x7C, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x18, 0x22, 0xA2, 0x72, 0x7A, 0x4C, 0x41, 0x34, 0x20, 0x1C, 0x6B, 0xA1, 0x01, 0x23, 0x9E, 0x46, 0x76, 0x4B, 0xFE, 0x44, 0x18, 0x47 ,
0x25, 0x76, 0x67, 0x76, 0x21, 0x20, 0xE0, 0x76, 0x26, 0x77, 0x01, 0x20, 0x60, 0x77, 0x72, 0x48, 0x61, 0x30, 0x11, 0x21, 0x01, 0x70, 0x94, 0x21, 0x41, 0x70, 0x04, 0x21, 0x01, 0x72, 0xD2, 0x21, 0x41, 0x72, 0xC5, 0x72, 0x1E, 0x21, 0x01, 0x73, 0x45, 0x73, 0x9E, 0x21, 0x81, 0x73, 0x01, 0x21, 0x01, 0x74, 0x46, 0x74, 0x81, 0x74, 0x11, 0x21, 0x41, 0x75, 0x94, 0x21, 0x81, 0x75, 0x04, 0x21, 0x01, 0x76, 0xAD, 0x20, 0x66, 0x49, 0x08, 0x60, 0x00, 0x24, 0x0F, 0x25, 0xFF, 0xFF, 0xC2, 0x01, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x29, 0x06, 0x09, 0x0E, 0x00, 0x20, 0x6A, 0x46, 0x01, 0x23, 0x9E, 0x46, 0x62, 0x4B, 0xFE, 0x44, 0x18, 0x47, 0x6B, 0x46, 0x18, 0x88, 0x40, 0x08, 0x0E, 0xD3, 0xA0, 0x00, 0x0F, 0x21, 0xCA, 0x43, 0x69, 0x46, 0x0E, 0x88, 0x16, 0x40, 0x01, 0xAF, 0x3E, 0x52, 0x49, 0x88, 0x11, 0x40, 0x68, 0x44, 0xC1, 0x80, 0x60, 0x1C, 0x04, 0x04, 0x24, 0x0C, 0x01, 0x3D, 0x0B, 0x2D, 0xE0, 0xDA, 0x60, 0x1E ,
0x00, 0x04, 0x00, 0x0C, 0x1D, 0xD0, 0x86, 0x46, 0x01, 0x1C, 0x01, 0xAD, 0x01, 0x22, 0xAE, 0x88, 0x90, 0x00, 0xC7, 0x5A, 0xB7, 0x42, 0x0A, 0xDA, 0xBC, 0x46, 0x07, 0x1C, 0x6F, 0x44, 0x7F, 0x88, 0x68, 0x44, 0x06, 0x80, 0xEE, 0x88, 0x46, 0x80, 0x60, 0x46, 0xA8, 0x80, 0xEF, 0x80, 0x04, 0x35, 0x50, 0x1C, 0x02, 0x04, 0x12, 0x0C, 0x01, 0x39, 0xE9, 0xD1, 0x70, 0x46, 0x01, 0x38, 0x86, 0x46, 0xE2, 0xD1, 0x99, 0x88, 0x68, 0x46, 0xC0, 0x88, 0x40, 0x18, 0x00, 0x04, 0x00, 0x0C, 0x42, 0x4B, 0x18, 0x80, 0x42, 0x49, 0x08, 0x1A, 0xFF, 0xFF, 0x58, 0x02, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x58, 0x80, 0x02, 0x2C, 0x1E, 0xDB, 0x65, 0x1E, 0x01, 0xAA, 0x01, 0x20, 0x01, 0x1C, 0x8C, 0x00, 0x6B, 0x46, 0xE6, 0x5A, 0x93, 0x88, 0xD4, 0x88, 0xE7, 0x18, 0xB7, 0x42, 0x0C, 0xDA, 0x06, 0x24, 0x44, 0x43, 0x38, 0x4B, 0x1B, 0x19, 0x1F, 0x80, 0x1C, 0x88, 0x34, 0x1B, 0x5C, 0x80, 0x01, 0x24, 0x1C, 0x71, 0x40, 0x1C, 0x00, 0x04 ,
0x00, 0x0C, 0x04, 0x32, 0x49, 0x1C, 0x09, 0x06, 0x09, 0x0E, 0x01, 0x3D, 0xE4, 0xD1, 0x00, 0x24, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x31, 0x48, 0x04, 0x70, 0x01, 0x20, 0x86, 0x46, 0x30, 0x48, 0xFE, 0x44, 0x00, 0x47, 0x2F, 0x49, 0x22, 0x1C, 0x08, 0x68, 0x00, 0x28, 0x02, 0xD0, 0x01, 0x20, 0x90, 0x40, 0x04, 0x43, 0x04, 0x31, 0x01, 0x32, 0x20, 0x2A, 0xF5, 0xD3, 0x2A, 0x48, 0x04, 0x60, 0x08, 0xB0, 0xF0, 0xBD, 0x5F, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2D, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0xC0, 0x46, 0xC0, 0x5F, 0x75, 0x64, 0x70, 0x00, 0xC0, 0xFF, 0xFF, 0xEE, 0x02, 0x18, 0x00, 0x96, 0x00, 0x00, 0x00, 0x46, 0xC0, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x00, 0xC0, 0x46, 0x5F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x00, 0xC0, 0x46, 0x5F, 0x64, 0x6E, 0x73, 0x2D, 0x73, 0x64, 0x00, 0x64, 0x65, 0x76, 0x3D, 0x43, 0x43, 0x33, 0x30, 0x30, 0x30, 0x00, 0xC0, 0x76, 0x65 ,
0x6E, 0x64, 0x6F, 0x72, 0x3D, 0x54, 0x65, 0x78, 0x61, 0x73, 0x2D, 0x49, 0x6E, 0x73, 0x74, 0x72, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x00, 0xC0, 0x46, 0xC0, 0x00, 0x00, 0x18, 0x00, 0xF3, 0x7E, 0x03, 0x00, 0xC6, 0x05, 0x00, 0x00, 0xDD, 0x7E, 0x03, 0x00, 0xE4, 0x62, 0x08, 0x00, 0xC9, 0xBA, 0x03, 0x00, 0x09, 0xB4, 0x03, 0x00, 0xA7, 0x64, 0x08, 0x00, 0x70, 0x64, 0x08, 0x00, 0xDD, 0x0A, 0x02, 0x00, 0x48, 0x32, 0x08, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xE8, 0x62, 0x08, 0x00, 0xE9, 0x62, 0x08, 0x00, 0xEA, 0x62, 0x08, 0x00, 0xEB, 0x62, 0x08, 0x00, 0x81, 0x03, 0x18, 0x00, 0x80, 0x7B, 0x08, 0x00, 0x84, 0xF3, 0x1A, 0x00, 0x0D, 0x49, 0x0E, 0x48, 0xFF, 0xFF, 0x84, 0x03, 0x18, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x88, 0x67, 0x0E, 0x48, 0x88, 0x64, 0x0E, 0x48, 0x48, 0x64, 0x0E, 0x48, 0xC8, 0x64, 0x0E, 0x48, 0x08, 0x65, 0x11, 0x48, 0x02, 0x1C, 0x04, 0x32, 0x0C, 0x4B, 0x13, 0x60, 0x0C, 0x4B, 0x93, 0x62, 0x0C, 0x4A ,
0x8A, 0x66, 0x0D, 0x49, 0x01, 0x60, 0x0D, 0x48, 0x0E, 0x49, 0x01, 0x60, 0x0E, 0x49, 0x41, 0x60, 0xF7, 0x46, 0x1C, 0x21, 0x08, 0x00, 0x1B, 0x7B, 0x08, 0x00, 0x11, 0x7B, 0x08, 0x00, 0x07, 0x7B, 0x08, 0x00, 0x39, 0x7B, 0x08, 0x00, 0x2F, 0x7B, 0x08, 0x00, 0x25, 0x7B, 0x08, 0x00, 0xFD, 0x7A, 0x08, 0x00, 0xDF, 0x7A, 0x08, 0x00, 0x50, 0x23, 0x08, 0x00, 0xD5, 0x7A, 0x08, 0x00, 0x58, 0x26, 0x08, 0x00, 0xF3, 0x7A, 0x08, 0x00, 0xE9, 0x7A, 0x08, 0x00 };
const unsigned char cRMdefaultParams[128] = { 0x03, 0x00, 0x01, 0x01, 0x14, 0x14, 0x00, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x23, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x23, 0x23, 0x23, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x01, 0x77, 0x80, 0x1D, 0x1F, 0x22, 0x26, 0x28, 0x29, 0x1A, 0x1F, 0x22, 0x24, 0x26, 0x28, 0x16, 0x1D, 0x1E, 0x20, 0x24, 0x25, 0x1E, 0x2D, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x15, 0x15, 0x15, 0x11, 0x15, 0x15, 0x0E, 0x00};
//
//Service Pack version P1.13.7.15.15 - FW patches
//
const unsigned char fw_patch[5700] = { 0x00, 0x01, 0x00, 0x00, 0x3C, 0x16, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x14, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x46, 0x25, 0xF0, 0x95, 0xFB, 0xE0, 0x6B, 0xD0, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x38, 0xFB, 0x2C, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x0A, 0xFB, 0x04, 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB8, 0xF1, 0x90, 0x0F, 0xA4, 0x16, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x66, 0xE0, 0x04, 0xA8, 0x35, 0x1D, 0x21, 0xF0, 0x99, 0xFC, 0x68, 0x46, 0x23, 0xF0, 0x28, 0xFB, 0x9A, 0xF8, 0x00, 0x00, 0x01, 0x28, 0x07, 0xD1, 0x28, 0x46, 0x05, 0xF0, 0xC3, 0xFE, 0x01, 0x46, 0x01, 0xAA, 0x00, 0x20, 0x21, 0xF0, 0x50, 0xF9, 0x28, 0x46, 0x05, 0xF0, 0xBB, 0xFE, 0x01, 0xA9, 0x21, 0xF0, 0x2A, 0xFA, 0xE9, 0x79, 0x4F, 0xEA, 0xE0, 0x00, 0x40, 0xB2, 0x11, 0xB1, 0x00, 0xF1, 0x06, 0x00, 0x40, 0xB2, 0xA8, 0x71, 0x1F, 0x38, 0x40, 0x00, 0xE8, 0x71, 0x30, 0x46 ,
0x01, 0xF0, 0x0D, 0xFF, 0x10, 0xF1, 0x00, 0x09, 0x4F, 0xF0, 0x00, 0x01, 0x09, 0xD0, 0x28, 0x68, 0x40, 0x0C, 0x09, 0xD3, 0xE8, 0x68, 0xC0, 0x0B, 0x03, 0xD2, 0x48, 0x46, 0xFF, 0xF7, 0xDD, 0xFE, 0x01, 0x21, 0x28, 0x68, 0x40, 0x0C, 0x0A, 0xD2, 0x38, 0x68, 0x40, 0x1C, 0x38, 0x60, 0x20, 0x68, 0x6F, 0xF3, 0x0F, 0x00, 0x20, 0x60, 0x22, 0x68, 0x38, 0x68, 0x10, 0x43, 0x20, 0x60, 0xE8, 0x68, 0xC0, 0x0B, 0x0F, 0xD3, 0xD8, 0xF8, 0x00, 0x00, 0x00, 0xF1, 0x01, 0x00, 0xC8, 0xF8, 0x00, 0x00, 0x20, 0x68, 0x6F, 0xF3, 0x1F, 0x40, 0x20, 0x60, 0xD8, 0xF8, 0x00, 0x20, 0x20, 0x68, 0x40, 0xEA, 0x02, 0x40, 0x20, 0x60, 0x49, 0xB9, 0xB9, 0xF1, 0x00, 0x0F, 0x03, 0xD1, 0x30, 0x46, 0x07, 0xF0, 0xBE, 0xF9, 0x02, 0xE0, 0x48, 0x46, 0x07, 0xF0, 0x06, 0xFA, 0x6C, 0x17, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x46, 0x0E, 0xF0, 0x85, 0xFB, 0x00, 0x9E, 0x00, 0x2E, 0x96, 0xD1, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xC0, 0x46 ,
0x9C, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0xF0, 0x2A, 0xFE, 0x74, 0x47, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x21, 0x21, 0xF0, 0x41, 0xFA, 0x20, 0x68, 0x18, 0x4B, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x21, 0xF0, 0x1C, 0xF9, 0x0A, 0xE0, 0x20, 0x68, 0x00, 0x68, 0x0C, 0x21, 0x40, 0xF0, 0x20, 0x00, 0x21, 0xF0, 0x14, 0xF9, 0x10, 0x57, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xA8, 0x20, 0xF0, 0x97, 0xF9, 0x01, 0x98, 0x5C, 0x57, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x20, 0xF0, 0x71, 0xF9, 0x03, 0x98, 0x00, 0x58, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0xF0, 0x20, 0xF9, 0x1C, 0x58, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0xF0, 0x12, 0xF9, 0x54, 0x58, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0xA8, 0x20, 0xF0, 0xF5, 0xF8, 0x04, 0xAB, 0x04, 0x62, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x79, 0x1F, 0xF0, 0x1B, 0xFD, 0x69, 0xE0, 0x60, 0x93, 0x00, 0x00, 0x40, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xA6, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1B, 0xF0, 0x39, 0xFB, 0x28, 0x46, 0x90, 0xA8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1B, 0xF0, 0x69, 0xF9, 0x1E, 0x48, 0x34, 0xAD, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x68, 0xFF, 0x29, 0x98, 0xAD, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0xD4, 0x21, 0xD4, 0xB2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0xD0, 0x1A, 0xF0, 0x47, 0xFC, 0x20, 0x98, 0xAC, 0xC5, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0xF0 ,
0xDB, 0xFA, 0x09, 0x49, 0x28, 0xC6, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0xF0, 0x9E, 0xFA, 0xDC, 0xD3, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x18, 0xF0, 0xAB, 0xFC, 0x00, 0xF0, 0x03, 0xF8, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xDF, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x17, 0xF0, 0xA8, 0xFD, 0xCC, 0xEB, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x38, 0x78, 0x17, 0xF0, 0x77, 0xF8, 0x38, 0x78, 0x16, 0xF0, 0xF0, 0xFF, 0xA8, 0xF7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0E, 0x49, 0x09, 0x68, 0x23, 0x22, 0x41, 0x61, 0xC8, 0xF7, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x31, 0x39, 0x2E, 0x33, 0x31, 0x34, 0x5F, 0x4E, 0x65, 0x77, 0x5F, 0x43, 0x43, 0x41, 0x5F, 0x61, 0x6C, 0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 0xC0, 0x74, 0x56, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xF9, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x16, 0xF0, 0x79, 0xF8 ,
0x12, 0xE0, 0x38, 0xFA, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0xA8, 0x16, 0xF0, 0x03, 0xF8, 0x32, 0x20, 0x94, 0xFB, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0C, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x14, 0xF0, 0x05, 0xFF, 0x01, 0xF0, 0x10, 0x1B, 0x01, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1E, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0xF0, 0x46, 0xBF, 0x18, 0x30, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x30, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0xF0, 0xD8, 0xFC, 0x9C, 0x31, 0x01, 0x00, 0x08, 0x00 ,
0x00, 0x00, 0x68, 0x46, 0x12, 0xF0, 0x51, 0xFC, 0xFE, 0xF7, 0xF0, 0x35, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x46, 0x12, 0xF0, 0x27, 0xFA, 0xFE, 0xF7, 0xF0, 0x3D, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0xA9, 0x11, 0xF0, 0x27, 0xFE, 0x20, 0x6F, 0xD0, 0x62, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0xB8, 0xFB, 0x80, 0x7E, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xDF, 0xF8, 0x58, 0x82, 0xE0, 0x7E, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0D, 0xF0, 0x6A, 0xFE, 0x0B, 0xF0, 0x9A, 0xF9, 0x03, 0x20, 0xA8, 0xF5, 0x88, 0x71, 0x08, 0x60, 0xF2, 0xF7, 0x16, 0xF9, 0x7A, 0x48, 0x6B, 0x49, 0x9C, 0x7F, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x70, 0x51, 0x4D, 0xC4, 0x7F, 0x01, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x40, 0x49, 0x00, 0xF1, 0x52, 0x00, 0x3A, 0x4A, 0xA8, 0x81, 0x28, 0x83, 0xE8, 0x83, 0xE8, 0x84, 0xA8, 0x85, 0x2A, 0x60, 0x39, 0x48, 0x41, 0xF2, 0x11, 0x12, 0x2A, 0x85, 0x18, 0x90, 0x19, 0x91 ,
0x39, 0x49, 0x1A, 0x91, 0x39, 0x49, 0x1B, 0x91, 0x39, 0x49, 0x20, 0x46, 0xDF, 0xF8, 0xC4, 0x90, 0x1C, 0x91, 0x38, 0x49, 0xDF, 0xF8, 0xC0, 0xB0, 0x31, 0x4E, 0x1D, 0x91, 0x48, 0x80, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0xF0, 0x7C, 0xFA, 0xB4, 0x80, 0x01, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x12, 0x66, 0x09, 0x84, 0x6B, 0x00, 0x20, 0x94, 0x70, 0x00, 0x20, 0xB4, 0x70, 0x00, 0x20, 0xC4, 0x78, 0x00, 0x20, 0x50, 0x7A, 0x00, 0x20, 0xFE, 0xFF, 0x03, 0x00, 0xA4, 0x70, 0x00, 0x20, 0xB0, 0x70, 0x00, 0x20, 0xB8, 0x70, 0x00, 0x20, 0x60, 0x55, 0x30, 0x80, 0x3C, 0x5C, 0x00, 0x20, 0x04, 0x74, 0x00, 0x20, 0xB8, 0xE4, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x78, 0x07, 0xF0, 0x01, 0xFC, 0x20, 0x78, 0x07, 0xF0, 0x7A, 0xFB, 0x04, 0x4D, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0xAD, 0xF1, 0x8C, 0x0D, 0x04, 0x68, 0x0F, 0x30, 0x03, 0x94, 0xFE, 0xF7, 0xDB, 0xFA, 0x04, 0xF1, 0x14, 0x00 ,
0x04, 0x90, 0x21, 0x7D, 0x00, 0x20, 0x21, 0xF0, 0x73, 0x01, 0x88, 0x29, 0x08, 0xBF, 0x01, 0x20, 0x05, 0x90, 0x03, 0x98, 0x00, 0x1D, 0x06, 0x90, 0x5D, 0x48, 0x00, 0x68, 0x01, 0x28, 0x40, 0xF0, 0xFA, 0x83, 0x5B, 0x4D, 0x5C, 0x48, 0xDF, 0xF8, 0x70, 0x91, 0x29, 0x68, 0xDF, 0xF8, 0x70, 0x81, 0xDF, 0xF8, 0x74, 0xA1, 0x88, 0x42, 0x21, 0xD1, 0x10, 0x22, 0x00, 0x21, 0x48, 0x46, 0x4F, 0x46, 0xFB, 0xF7, 0xB7, 0xFE, 0x10, 0x22, 0x00, 0x21, 0x40, 0x46, 0xFB, 0xF7, 0xB2, 0xFE, 0x54, 0x49, 0x08, 0x68, 0x40, 0xF4, 0x80, 0x10, 0x08, 0x60, 0x01, 0x20, 0x51, 0x46, 0x08, 0x60, 0x00, 0x21, 0x29, 0x60, 0x39, 0x78, 0x46, 0x46, 0x00, 0x91, 0x31, 0x78, 0x41, 0xF2, 0x11, 0x13, 0x04, 0x22, 0x01, 0x91, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF3, 0xF7, 0x41, 0xFC, 0x51, 0x46, 0x07, 0x91, 0x08, 0x68, 0x56, 0x49, 0xDF, 0xF8, 0x5C, 0xB1, 0x01, 0x28, 0x08, 0x91, 0x56, 0x49, 0xDF, 0xF8, 0x48, 0xA1, 0x09, 0x91, 0x55, 0x49 ,
0x0A, 0x91, 0x44, 0x49, 0x0B, 0x91, 0x44, 0x49, 0x0C, 0x91, 0x44, 0x49, 0x0D, 0x91, 0x44, 0x49, 0x0E, 0x91, 0x44, 0x49, 0x0F, 0x91, 0x44, 0x49, 0x10, 0x91, 0x44, 0x49, 0xCC, 0x4D, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x11, 0x91, 0x44, 0x49, 0x12, 0x91, 0x44, 0x49, 0x13, 0x91, 0x44, 0x49, 0x14, 0x91, 0x44, 0x49, 0x15, 0x91, 0x44, 0x49, 0x16, 0x91, 0x9F, 0x49, 0x17, 0x91, 0x9F, 0x49, 0x18, 0x91, 0x9F, 0x49, 0x19, 0x91, 0x9F, 0x49, 0x1A, 0x91, 0x9F, 0x49, 0x1B, 0x91, 0x9F, 0x49, 0x1C, 0x91, 0x9F, 0x49, 0x1D, 0x91, 0x9F, 0x49, 0x1E, 0x91, 0x9F, 0x49, 0x1F, 0x91, 0x40, 0xF0, 0x00, 0x81, 0x04, 0x98, 0x40, 0x78, 0x00, 0xF0, 0x03, 0x01, 0x01, 0x29, 0x40, 0xF0, 0xF9, 0x80, 0x04, 0x99, 0x09, 0x78, 0x01, 0xF0, 0x0C, 0x01, 0x08, 0x29, 0x40, 0xF0, 0xF2, 0x80, 0x06, 0x99, 0x09, 0x88, 0xA1, 0xF1, 0x3C, 0x01, 0x0E, 0xB2, 0x05, 0x99, 0x11, 0xB1, 0xA6, 0xF1, 0x02, 0x06, 0x36, 0xB2, 0xC0, 0x09, 0x4F, 0xF0 ,
0x00, 0x07, 0x15, 0xD3, 0x08, 0x3E, 0x36, 0xB2, 0x03, 0x2E, 0x10, 0xD0, 0x17, 0x2E, 0x0E, 0xD0, 0x08, 0x3E, 0x36, 0xB2, 0x03, 0x2E, 0x08, 0xD0, 0x17, 0x2E, 0x06, 0xD0, 0x36, 0x1F, 0x36, 0xB2, 0x03, 0x2E, 0x14, 0xBF, 0x17, 0x2E, 0x02, 0x27, 0x02, 0xE0, 0x03, 0x27, 0x00, 0xE0, 0x01, 0x27, 0x03, 0x2E, 0x18, 0xBF, 0x17, 0x2E, 0x04, 0x9A, 0x40, 0xF0, 0xC8, 0x80, 0x0A, 0x32, 0x12, 0xF8, 0x01, 0x1B, 0x05, 0x24, 0x12, 0xF8, 0x01, 0x3B, 0x4B, 0x40, 0x64, 0x1E, 0xD9, 0xB2, 0xF9, 0xD1, 0x81, 0xEA, 0x21, 0x11, 0x03, 0x2E, 0x94, 0x4E, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x0F, 0x01, 0x48, 0x46, 0x35, 0xD0, 0x43, 0x46, 0xCA, 0x5C, 0x52, 0x1C, 0xCA, 0x54, 0x0C, 0x18, 0x33, 0xE0, 0x50, 0x57, 0x02, 0x00, 0x04, 0x74, 0x00, 0x20, 0x34, 0x12, 0x66, 0x09, 0x60, 0x57, 0x02, 0x00, 0x70, 0x57, 0x02, 0x00, 0xC8, 0x48, 0x30, 0x80, 0x4C, 0x57, 0x02, 0x00, 0x88, 0x57, 0x02, 0x00, 0x80, 0x57, 0x02, 0x00 ,
0x18, 0x58, 0x02, 0x00, 0x20, 0x58, 0x02, 0x00, 0x28, 0x58, 0x02, 0x00, 0x30, 0x58, 0x02, 0x00, 0x38, 0x58, 0x02, 0x00, 0x40, 0x58, 0x02, 0x00, 0xE4, 0x58, 0x02, 0x00, 0xE2, 0x58, 0x02, 0x00, 0x14, 0x58, 0x02, 0x00, 0xEF, 0x58, 0x02, 0x00, 0xE0, 0x58, 0x02, 0x00, 0xEE, 0x58, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0xE6, 0x58, 0x02, 0x00, 0xE8, 0x58, 0x02, 0x00, 0x0C, 0x18, 0x20, 0x78, 0x40, 0x1C, 0x20, 0x70, 0x20, 0x78, 0x43, 0x46, 0x03, 0xEB, 0x01, 0x08, 0x0A, 0x28, 0x76, 0xDB, 0x98, 0xF8, 0x00, 0x00, 0x0A, 0x28, 0x72, 0xDB, 0x94, 0x48, 0x00, 0x25, 0x01, 0x60, 0x04, 0x98, 0x00, 0xF1, 0x0A, 0x09, 0x40, 0x78, 0x41, 0x08, 0x24, 0xBF, 0x04, 0x99, 0x09, 0x1D, 0x04, 0xD2, 0x80, 0x08, 0x2E, 0xBF, 0x49, 0x46, 0x04, 0x99, 0x10, 0x31, 0x0B, 0x98, 0x06, 0x22, 0xFA, 0xF7, 0xB9, 0xFC, 0x0C, 0x98, 0x06, 0x22, 0x49, 0x46, 0xFA, 0xF7, 0xB4, 0xFC, 0x9B, 0x48, 0x9A, 0x49, 0x5C, 0x4F, 0x02, 0x00, 0xC8, 0x00 ,
0x00, 0x00, 0x00, 0x78, 0x08, 0x22, 0x08, 0x60, 0x58, 0x46, 0x07, 0x60, 0x0D, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xAF, 0xFD, 0x08, 0x22, 0x0E, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xAA, 0xFD, 0x08, 0x22, 0x0F, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xA5, 0xFD, 0x08, 0x22, 0x10, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0xA0, 0xFD, 0x08, 0x22, 0x11, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0x9B, 0xFD, 0x08, 0x22, 0x12, 0x98, 0x29, 0x46, 0xFB, 0xF7, 0x96, 0xFD, 0x07, 0x99, 0x02, 0x20, 0x08, 0x60, 0x13, 0x99, 0x28, 0x46, 0x08, 0x80, 0x08, 0x99, 0x08, 0x70, 0x14, 0x99, 0x08, 0x70, 0x15, 0x99, 0x08, 0x60, 0x16, 0x99, 0x08, 0x70, 0x17, 0x99, 0x08, 0x60, 0x18, 0x99, 0x08, 0x60, 0x19, 0x99, 0x08, 0x60, 0x09, 0x99, 0x08, 0x80, 0x0A, 0x99, 0x08, 0x80, 0x1A, 0x99, 0x08, 0x80, 0x7D, 0x49, 0x0D, 0x60, 0x1B, 0x99, 0x08, 0x70, 0x1C, 0x99, 0x08, 0x70, 0x1D, 0x99, 0x08, 0x70, 0x1E, 0x99, 0x08, 0x80, 0x1F, 0x99, 0x08, 0x80, 0x51, 0x46, 0x08, 0x80 ,
0x20, 0x78, 0x00, 0x96, 0x04, 0x22, 0x01, 0x90, 0x98, 0xF8, 0x00, 0x00, 0x41, 0xF2, 0x14, 0x13, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF3, 0xF7, 0x07, 0xFB, 0x07, 0x98, 0xA2, 0x49, 0x00, 0x68, 0x20, 0x91, 0xA2, 0x49, 0x05, 0x28, 0x21, 0x91, 0x9E, 0x49, 0x22, 0x91, 0x40, 0xF0, 0x37, 0x82, 0x04, 0x98, 0x40, 0x78, 0x24, 0x50, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x41, 0x08, 0x24, 0xBF, 0x04, 0x99, 0x09, 0x1D, 0x05, 0xD2, 0x80, 0x08, 0x27, 0xBF, 0x04, 0x99, 0x0A, 0x31, 0x04, 0x99, 0x10, 0x31, 0x0B, 0x98, 0xF8, 0xF7, 0x2D, 0xFC, 0x01, 0x28, 0x04, 0x98, 0x40, 0xF0, 0x23, 0x82, 0x40, 0x78, 0x00, 0xF0, 0x03, 0x00, 0x03, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x07, 0xBF, 0x04, 0x99, 0x10, 0x31, 0x04, 0x99, 0x0A, 0x31, 0x13, 0xE0, 0x48, 0x58, 0x02, 0x00, 0x4C, 0x58, 0x02, 0x00, 0x50, 0x58, 0x02, 0x00, 0xF0, 0x58, 0x02, 0x00, 0xF2, 0x58, 0x02, 0x00, 0xF3, 0x58, 0x02, 0x00, 0xF4, 0x58, 0x02, 0x00, 0xEA, 0x58 ,
0x02, 0x00, 0xEC, 0x58, 0x02, 0x00, 0x04, 0x99, 0x18, 0x31, 0x0C, 0x98, 0xF8, 0xF7, 0x06, 0xFC, 0x04, 0x99, 0x01, 0x28, 0x40, 0xF0, 0xFC, 0x81, 0x49, 0x78, 0x01, 0xF0, 0x03, 0x01, 0x01, 0x29, 0x40, 0xF0, 0xF6, 0x81, 0x59, 0x46, 0x09, 0x68, 0x04, 0x9A, 0x8E, 0x46, 0x51, 0x46, 0xD2, 0x8A, 0x0B, 0x88, 0x12, 0x11, 0x93, 0x42, 0x00, 0xF0, 0x37, 0x82, 0x0A, 0x80, 0x06, 0x99, 0x09, 0x88, 0x3C, 0x39, 0x0B, 0xB2, 0x71, 0x46, 0x49, 0x1E, 0x09, 0xD0, 0x49, 0x1E, 0x04, 0xD0, 0x49, 0x1E, 0x08, 0xD1, 0xA3, 0xF1, 0x10, 0x03, 0x04, 0xE0, 0xA3, 0xF1, 0x14, 0x03, 0x01, 0xE0, 0xA3, 0xF1, 0x08, 0x03, 0x1B, 0xB2, 0x05, 0x98, 0x10, 0xB1, 0xA3, 0xF1, 0x02, 0x03, 0x1B, 0xB2, 0xEC, 0x50, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0xF1, 0xCE, 0x81, 0x16, 0x98, 0x40, 0xF2, 0x77, 0x51, 0x99, 0x42, 0x0B, 0x90, 0x14, 0x98, 0x05, 0x90, 0x00, 0xF0, 0xA3, 0x81, 0x08, 0x46, 0x00, 0xF1, 0x3C, 0x00, 0x98, 0x42 ,
0x05, 0x9A, 0x00, 0xF0, 0x9A, 0x81, 0xDF, 0xF8, 0x48, 0x82, 0x14, 0x78, 0x0B, 0x9A, 0xBB, 0x2C, 0x12, 0x78, 0x0C, 0x92, 0x63, 0xD1, 0xDD, 0xF8, 0x68, 0xC0, 0xBC, 0xF9, 0x00, 0x20, 0x91, 0x42, 0x18, 0xBF, 0x90, 0x42, 0x5B, 0xD1, 0x1C, 0x2B, 0x4F, 0xF0, 0x00, 0x00, 0xC0, 0xF2, 0x82, 0x81, 0x3D, 0x2B, 0x13, 0x9D, 0x80, 0xF2, 0x7E, 0x81, 0xA3, 0xF1, 0x1C, 0x01, 0x09, 0xB2, 0x29, 0x80, 0x1E, 0x9A, 0xDD, 0xF8, 0x30, 0x90, 0xB2, 0xF9, 0x00, 0x60, 0xB9, 0xF1, 0x01, 0x0F, 0x15, 0xD1, 0xDD, 0xF8, 0x24, 0x90, 0x03, 0x2E, 0x0D, 0xDA, 0xB9, 0xF9, 0x00, 0x70, 0xB9, 0x42, 0x07, 0xD0, 0x01, 0x26, 0x16, 0x80, 0x4A, 0x46, 0x0E, 0x46, 0x03, 0xE0, 0xC0, 0x46, 0x90, 0x57, 0x02, 0x00, 0x76, 0x1C, 0x16, 0x80, 0x1B, 0x9A, 0x16, 0x78, 0x1D, 0x9A, 0x16, 0x70, 0x0C, 0x9A, 0x1F, 0x9E, 0x02, 0x2A, 0x28, 0xD1, 0xB6, 0xF9, 0x00, 0x20, 0xBE, 0xF1, 0x00, 0x0F, 0x1A, 0xD0, 0x03, 0x2A, 0x35, 0x46, 0x0B, 0xDA, 0x0A, 0x9E ,
0xB6, 0xF9, 0x00, 0x70, 0xB9, 0x42, 0x04, 0xD0, 0x01, 0x22, 0x2A, 0x80, 0x0A, 0x46, 0x35, 0x46, 0x00, 0xE0, 0xB4, 0x51, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x52, 0x1C, 0x2A, 0x80, 0x1C, 0x99, 0x0A, 0x78, 0x1D, 0x99, 0x0A, 0x70, 0x0F, 0xE0, 0xC0, 0x46, 0x58, 0x57, 0x02, 0x00, 0xA6, 0x64, 0x00, 0x20, 0x54, 0x57, 0x02, 0x00, 0x28, 0x80, 0x05, 0x99, 0x08, 0x70, 0x08, 0x9A, 0x11, 0x78, 0x41, 0xF0, 0x04, 0x01, 0x11, 0x70, 0x04, 0x46, 0x45, 0x46, 0xAC, 0xF8, 0x00, 0x00, 0x28, 0x70, 0xCC, 0x2C, 0x09, 0x9A, 0x40, 0xF0, 0x00, 0x81, 0xDD, 0xF8, 0x7C, 0xC0, 0x0A, 0x99, 0x1E, 0x9F, 0x45, 0x46, 0xB1, 0xF9, 0x00, 0x60, 0xB2, 0xF9, 0x00, 0x90, 0x28, 0x78, 0xCD, 0xF8, 0x50, 0xC0, 0x16, 0x91, 0x0A, 0x97, 0x13, 0x92, 0x09, 0x95, 0x0C, 0x99, 0x01, 0x29, 0x05, 0xD1, 0x05, 0x9A, 0xB0, 0xEB, 0x49, 0x0F, 0x01, 0xD1, 0x00, 0x21, 0x11, 0x70, 0x0C, 0x99, 0x02, 0x29, 0x05, 0xD1, 0x05, 0x9A, 0xB0, 0xEB, 0x46, 0x0F ,
0x01, 0xD1, 0x00, 0x21, 0x11, 0x70, 0xB3, 0xF5, 0x14, 0x7F, 0x40, 0xF3, 0xBA, 0x80, 0x40, 0xF2, 0x51, 0x31, 0x99, 0x42, 0x08, 0x99, 0x40, 0xF3, 0xB4, 0x80, 0x09, 0x78, 0x06, 0x29, 0x00, 0xF0, 0xB0, 0x80, 0xA3, 0xF2, 0x51, 0x21, 0x0B, 0xB2, 0x4F, 0xEA, 0xE3, 0x01, 0x03, 0xEB, 0x11, 0x71, 0x4F, 0xEA, 0x21, 0x11, 0xCA, 0xB2, 0x4F, 0xEA, 0xE3, 0x01, 0x03, 0xEB, 0x11, 0x71, 0x15, 0x9D, 0x21, 0xF0, 0x0F, 0x01, 0xA3, 0xEB, 0x01, 0x03, 0x1D, 0x99, 0x2E, 0x68, 0x7C, 0x52, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x91, 0xF8, 0x00, 0xE0, 0x5F, 0xFA, 0x83, 0xF8, 0x60, 0xB1, 0x31, 0x18, 0x11, 0xF8, 0x01, 0x1C, 0x51, 0x40, 0xCB, 0xB2, 0x07, 0xE0, 0xC0, 0x46, 0x58, 0x58, 0x02, 0x00, 0x54, 0x58, 0x02, 0x00, 0xDC, 0x58, 0x02, 0x00, 0x13, 0x46, 0x19, 0x99, 0xDD, 0xF8, 0x6C, 0xA0, 0xDD, 0xF8, 0x70, 0xB0, 0xD1, 0xF8, 0x00, 0xC0, 0x00, 0xF0, 0x0F, 0x01, 0x99, 0x42, 0x22, 0xD0, 0x0A, 0x9B, 0x86, 0x45, 0x9A, 0xF8 ,
0x00, 0x10, 0xB3, 0xF9, 0x00, 0x30, 0x9B, 0xF8, 0x00, 0x50, 0x15, 0xDD, 0x37, 0x5C, 0x44, 0x1C, 0x82, 0xEA, 0x07, 0x0C, 0x04, 0xF0, 0x0F, 0x07, 0x67, 0x45, 0x0B, 0xD0, 0xA6, 0x45, 0x06, 0x44, 0x0A, 0xDD, 0x76, 0x78, 0x72, 0x40, 0x86, 0x1C, 0x06, 0xF0, 0x0F, 0x06, 0x96, 0x42, 0x03, 0xD1, 0xC0, 0x1C, 0x4D, 0xE0, 0x80, 0x1C, 0x4B, 0xE0, 0x05, 0x9E, 0x00, 0x22, 0x32, 0x70, 0x4A, 0xE0, 0x00, 0xF0, 0x1F, 0x01, 0x01, 0x22, 0x8A, 0x40, 0x17, 0x99, 0xC4, 0x10, 0x0B, 0x68, 0x24, 0xF0, 0x03, 0x01, 0x5C, 0xF8, 0x01, 0x70, 0x3A, 0x42, 0x32, 0xD1, 0x5F, 0x58, 0x3A, 0x42, 0x06, 0x44, 0x1F, 0xD0, 0x18, 0x9B, 0x37, 0x78, 0x1B, 0x68, 0xB8, 0x45, 0x04, 0xD1, 0x58, 0x58, 0x02, 0x42, 0x19, 0xD0, 0x63, 0x46, 0x15, 0xE0, 0xA1, 0x10, 0x8C, 0x00, 0x19, 0x59, 0x91, 0x43, 0x19, 0x51, 0x00, 0x90, 0x30, 0x78, 0x01, 0x90, 0x44, 0x53, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x03, 0x20, 0x06, 0x21, 0x02, 0x46, 0x4D, 0xF6 ,
0x80, 0x53, 0xF3, 0xF7, 0x63, 0xF9, 0x09, 0x99, 0x28, 0x68, 0x0E, 0x78, 0x36, 0x18, 0x06, 0xE0, 0xE3, 0x58, 0x02, 0x00, 0xA0, 0x10, 0x81, 0x00, 0x58, 0x58, 0x02, 0x43, 0x5A, 0x50, 0x86, 0xF8, 0x00, 0x80, 0x0B, 0x98, 0x00, 0x78, 0x0C, 0x90, 0x13, 0x98, 0xB0, 0xF9, 0x00, 0x90, 0x09, 0x98, 0x00, 0x78, 0x0A, 0x9A, 0x40, 0x1C, 0x9B, 0xF8, 0x00, 0x50, 0x9A, 0xF8, 0x00, 0x10, 0xB2, 0xF9, 0x00, 0x30, 0x09, 0x9A, 0xC0, 0xB2, 0x10, 0x70, 0x0C, 0x9A, 0x01, 0x2A, 0x03, 0xD1, 0x88, 0x42, 0xC8, 0xBF, 0x8A, 0xF8, 0x00, 0x00, 0x0C, 0x99, 0x02, 0x29, 0x07, 0xD1, 0xA8, 0x42, 0xC8, 0xBF, 0x8B, 0xF8, 0x00, 0x00, 0x02, 0xE0, 0x0A, 0x98, 0xB0, 0xF9, 0x00, 0x30, 0xB9, 0xF1, 0x00, 0x0F, 0x06, 0xDD, 0x03, 0x2B, 0x04, 0xD1, 0x11, 0x98, 0x01, 0x22, 0x49, 0x46, 0x00, 0xF0, 0x72, 0xFB, 0x16, 0x98, 0xB0, 0xF9, 0x00, 0x10, 0x14, 0x98, 0x00, 0x29, 0xB0, 0xF9, 0x00, 0x00, 0x05, 0xDD, 0x03, 0x28, 0x03, 0xD1, 0x12, 0x98 ,
0x02, 0x22, 0x00, 0xF0, 0x64, 0xFB, 0x05, 0x98, 0x04, 0x78, 0x0B, 0x98, 0x00, 0x78, 0x0C, 0x90, 0x08, 0x98, 0xBB, 0x2C, 0x01, 0x78, 0x02, 0xD0, 0xAA, 0x2C, 0x2F, 0xD0, 0x31, 0xE0, 0x0C, 0x98, 0x01, 0x28, 0x0B, 0xD1, 0x0D, 0x98, 0x17, 0x9A, 0x10, 0x60, 0x0C, 0x54, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x0F, 0x98, 0x18, 0x9A, 0x10, 0x60, 0x19, 0x9A, 0x11, 0x98, 0x10, 0x60, 0x47, 0x4A, 0x15, 0x98, 0x02, 0x60, 0x0C, 0x98, 0x02, 0x28, 0x0B, 0xD1, 0x0E, 0x98, 0x17, 0x9A, 0x10, 0x60, 0x10, 0x98, 0x18, 0x9A, 0x10, 0x60, 0x19, 0x9A, 0x12, 0x98, 0x10, 0x60, 0x41, 0x4A, 0x15, 0x98, 0x02, 0x60, 0xCC, 0x20, 0x0F, 0xE0, 0x08, 0x99, 0x09, 0x78, 0x0C, 0xE0, 0x02, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x0B, 0x99, 0x08, 0x70, 0x1A, 0x99, 0x0B, 0x80, 0x13, 0x99, 0x00, 0x20, 0x08, 0x80, 0x08, 0x98, 0x01, 0x78, 0xBB, 0x20, 0x05, 0x9A, 0x10, 0x70, 0x06, 0x29, 0x07, 0x99, 0x11, 0xD1, 0x06, 0x20, 0x08, 0x60, 0x20, 0x98 ,
0x00, 0x25, 0x05, 0x70, 0x21, 0x98, 0x29, 0x46, 0x04, 0x22, 0xFB, 0xF7, 0x27, 0xFB, 0x01, 0x20, 0x00, 0xF0, 0x3A, 0xFA, 0x02, 0x20, 0x00, 0xF0, 0x37, 0xFA, 0x22, 0x98, 0x05, 0x60, 0x07, 0x98, 0x04, 0x99, 0x00, 0x68, 0x07, 0x28, 0x44, 0xD1, 0x09, 0x78, 0x03, 0x9C, 0x80, 0x29, 0x40, 0xD1, 0x38, 0x34, 0x21, 0x78, 0x64, 0x1C, 0x22, 0x46, 0x00, 0x29, 0x3A, 0xD1, 0x20, 0x98, 0x90, 0xF8, 0x00, 0xA0, 0x22, 0x98, 0x05, 0x90, 0xD0, 0xF8, 0x00, 0x90, 0x51, 0x46, 0x48, 0x46, 0xFD, 0xF7, 0x79, 0xF9, 0x5F, 0xFA, 0x80, 0xF8, 0x21, 0x9F, 0x15, 0x78, 0x51, 0x46, 0x48, 0x46, 0x17, 0xF8, 0x08, 0x30, 0xFD, 0xF7, 0xD4, 0x54, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x6F, 0xF9, 0x1E, 0x46, 0x1B, 0x1D, 0xC0, 0xB2, 0x38, 0x5C, 0x00, 0x1D, 0xA8, 0x42, 0x28, 0x46, 0x07, 0xDD, 0x80, 0x18, 0x82, 0x1C, 0x10, 0x78, 0x2D, 0x18, 0xAD, 0x1C, 0xAD, 0xB2, 0xAB, 0x42, 0xF7, 0xDC, 0x04, 0xF8, 0x01, 0x6B, 0x11, 0x49, 0x32, 0x46 ,
0x20, 0x46, 0x01, 0xEB, 0x48, 0x11, 0xFA, 0xF7, 0xDC, 0xF9, 0xAD, 0x1B, 0xFF, 0x20, 0x34, 0x19, 0xAD, 0x1E, 0x04, 0xF8, 0x01, 0x0B, 0x25, 0x70, 0x05, 0x98, 0x01, 0x68, 0x49, 0x1C, 0x01, 0x60, 0x07, 0x98, 0x00, 0x68, 0x07, 0x28, 0x04, 0xD0, 0x06, 0x99, 0x08, 0x68, 0x20, 0xF4, 0x80, 0x30, 0x08, 0x60, 0x23, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xC0, 0x46, 0x94, 0x57, 0x02, 0x00, 0xD4, 0x57, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x6E, 0x48, 0x2D, 0xE9, 0xF0, 0x47, 0x6E, 0x4D, 0x82, 0x89, 0x4A, 0xF6, 0x55, 0x21, 0xAD, 0xF5, 0xFE, 0x7D, 0x91, 0x42, 0x4F, 0xF0, 0x00, 0x01, 0xAD, 0xF1, 0x38, 0x0D, 0x12, 0xD1, 0x29, 0x60, 0x68, 0x4A, 0x11, 0x70, 0x41, 0xF2, 0x10, 0x41, 0x81, 0x81, 0x4F, 0xF6, 0xFF, 0x70, 0x66, 0x49, 0x08, 0x60, 0x28, 0x68, 0x00, 0x90, 0x02, 0x22, 0x05, 0x21, 0x03, 0x20, 0x41, 0xF2, 0x34, 0x23, 0xF3, 0xF7, 0x48, 0xF8, 0x29, 0x68, 0x61, 0x4C, 0x01, 0x29, 0x20, 0x68, 0x40, 0xF0, 0xAF, 0x80 ,
0x5F, 0x4D, 0x02, 0x28, 0x29, 0x68, 0x23, 0xD1, 0x9C, 0x55, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x5E, 0x48, 0x00, 0x68, 0x5F, 0x4A, 0x12, 0x5C, 0x00, 0x92, 0x01, 0x91, 0x5E, 0x49, 0x09, 0x68, 0x02, 0x91, 0x5B, 0x49, 0x0B, 0x5C, 0x03, 0x20, 0x07, 0x21, 0x04, 0x22, 0xF3, 0xF7, 0x2E, 0xF8, 0x5B, 0x49, 0x4A, 0x79, 0x59, 0x48, 0x00, 0x92, 0x02, 0x79, 0x01, 0x92, 0x40, 0x79, 0x04, 0x22, 0x02, 0x90, 0x03, 0x20, 0x0B, 0x79, 0x07, 0x21, 0xF3, 0xF7, 0x20, 0xF8, 0x03, 0x20, 0x20, 0x60, 0xEC, 0xF7, 0x1A, 0xFF, 0x20, 0x68, 0x29, 0x68, 0x04, 0x28, 0x15, 0xD1, 0x0D, 0x20, 0x8D, 0xF8, 0x10, 0x00, 0x00, 0x25, 0x8D, 0xF8, 0x14, 0x50, 0x8D, 0xF8, 0x15, 0x10, 0x28, 0x46, 0x63, 0x21, 0x00, 0xF0, 0xAA, 0xFB, 0x63, 0x21, 0x28, 0x46, 0x00, 0xF0, 0xFA, 0xFA, 0x03, 0xA9, 0x04, 0xA8, 0xE0, 0xF7, 0xCA, 0xFC, 0x05, 0x20, 0x20, 0x60, 0x46, 0x4D, 0x05, 0x28, 0x29, 0x68, 0x01, 0xF1, 0x01, 0x01, 0x29, 0x60, 0x1D, 0xD1 ,
0x44, 0x4A, 0x8A, 0x42, 0x1A, 0xD1, 0x43, 0x48, 0x01, 0x68, 0x00, 0x91, 0x40, 0x68, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0x06, 0x21, 0x41, 0x4E, 0x33, 0x46, 0x22, 0x3B, 0xF2, 0xF7, 0xEB, 0xFF, 0x3E, 0x48, 0x01, 0x68, 0x00, 0x91, 0x40, 0x68, 0x33, 0x46, 0x06, 0x21, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0xF2, 0xF7, 0xE0, 0xFF, 0x00, 0x20, 0x28, 0x60, 0x20, 0x68, 0x06, 0x28, 0x47, 0xD1, 0x4F, 0xF0, 0x64, 0x56, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x07, 0x0A, 0xC4, 0xF8, 0x00, 0xA0, 0x03, 0x20, 0x48, 0xF2, 0x70, 0x53, 0x01, 0x22, 0x04, 0x21, 0xF2, 0xF7, 0xD0, 0xFF, 0xDF, 0xF8, 0xCC, 0x80, 0x31, 0x4F, 0x48, 0xF2, 0x70, 0x59, 0x01, 0x25, 0x49, 0xEA, 0x05, 0x03, 0x01, 0x22, 0x04, 0x21, 0x03, 0x20, 0xF2, 0xF7, 0xC3, 0xFF, 0x00, 0x24, 0x17, 0xF8, 0x02, 0x0F, 0x20, 0xE0, 0x69, 0x01, 0x04, 0xEB, 0x08, 0x02, 0x88, 0x18, 0xC6, 0x1C, 0x43, 0x78, 0x00, 0x93, 0x80, 0x78, 0x01, 0x90, 0x30, 0x78, 0x02, 0x90 ,
0x53, 0x5C, 0x51, 0x46, 0x04, 0x22, 0x03, 0x20, 0xF2, 0xF7, 0xAE, 0xFF, 0x38, 0x78, 0x01, 0x1B, 0xB1, 0xF1, 0xFF, 0x3F, 0x08, 0xD1, 0xF0, 0x78, 0x00, 0x90, 0xB3, 0x78, 0x03, 0x20, 0x02, 0x22, 0x05, 0x21, 0xF2, 0xF7, 0xA1, 0xFF, 0x38, 0x78, 0x24, 0x1D, 0xE4, 0xB2, 0xA0, 0x42, 0xDC, 0xDC, 0xAD, 0x1C, 0xED, 0xB2, 0x04, 0x2D, 0xCD, 0xDB, 0x63, 0x21, 0x4F, 0xF4, 0x05, 0x70, 0xF1, 0xF7, 0xA3, 0xFC, 0xE1, 0xF7, 0x85, 0xFD, 0x7F, 0xB0, 0x0E, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0xC0, 0x46, 0x04, 0x74, 0x00, 0x20, 0x50, 0x57, 0x02, 0x00, 0x6C, 0x5D, 0x02, 0x00, 0x40, 0x00, 0x3D, 0x80, 0x4C, 0x57, 0x02, 0x00, 0x58, 0x57, 0x02, 0x00, 0x90, 0x57, 0x02, 0x00, 0x60, 0x57, 0x02, 0x00, 0x70, 0x57, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0x80, 0x57, 0x02, 0x00, 0x2C, 0x57, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x88, 0x57, 0x02, 0x00, 0x54, 0x57, 0x02, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x38, 0x58, 0x02, 0x00, 0x40, 0x58 ,
0x02, 0x00, 0x66, 0x55, 0xDD, 0xEE, 0xDB, 0x58, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x57, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x58, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x4A, 0x4A, 0x49, 0x4D, 0x00, 0x90, 0xB2, 0xF9, 0x00, 0x20, 0x43, 0xA3, 0x29, 0x78, 0x01, 0x93, 0x43, 0xA3, 0x01, 0x28, 0x02, 0x93, 0x47, 0x4E, 0xDF, 0xF8, 0x1C, 0x81, 0xDF, 0xF8, 0x1C, 0x91, 0x1E, 0xD0, 0x43, 0x48, 0x04, 0x78, 0x48, 0x01, 0x87, 0x19, 0x30, 0x18, 0x01, 0x99, 0x06, 0x22, 0xF9, 0xF7, 0xC8, 0xFF, 0x40, 0x46, 0x01, 0x78, 0x00, 0x68, 0x07, 0xF1, 0x06, 0x07, 0x07, 0xF8, 0x01, 0x1B, 0x07, 0xF8, 0x01, 0x4B, 0x4F, 0xF0, 0x00, 0x01, 0x07, 0xF8, 0x01, 0x1B, 0x20, 0xB9, 0x39, 0x70, 0x28, 0x78, 0x4E, 0x46, 0x0A, 0x21, 0x58, 0xE0, 0xDF, 0xF8, 0xE4, 0xB0, 0x0F, 0xE0, 0xD4, 0xB2, 0x48, 0x01, 0x87, 0x19, 0x30, 0x18, 0x02, 0x99, 0x07, 0x22, 0xF9, 0xF7, 0xAA, 0xFF, 0xFF, 0x1D, 0x00, 0x20, 0xDF, 0xF8, 0xCC, 0xB0, 0x07, 0xF8, 0x01, 0x4B, 0x07, 0xF8, 0x01, 0x0B, 0x16, 0x2C, 0xB2, 0x46, 0xAE, 0xBF, 0x14, 0x20, 0x84, 0x59 ,
0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x60, 0x1E, 0xC0, 0xB2, 0x38, 0x70, 0x4E, 0x46, 0x7F, 0x1C, 0x40, 0x1C, 0xC2, 0xB2, 0x28, 0x78, 0x5B, 0x46, 0x00, 0x21, 0x32, 0x54, 0x38, 0x46, 0x00, 0xF0, 0xBC, 0xF9, 0x28, 0x78, 0x16, 0x2C, 0x31, 0x5C, 0x01, 0xF1, 0x0A, 0x01, 0x31, 0x54, 0x00, 0xF1, 0x01, 0x00, 0xC0, 0xB2, 0x28, 0x70, 0x2B, 0xDB, 0x00, 0x99, 0x0A, 0xEB, 0x40, 0x10, 0x07, 0x46, 0x01, 0x29, 0xA4, 0xF1, 0x01, 0x09, 0x09, 0xD0, 0x01, 0x99, 0x06, 0x22, 0xF9, 0xF7, 0x79, 0xFF, 0x40, 0x46, 0x00, 0x78, 0xBF, 0x1D, 0x07, 0xF8, 0x01, 0x0B, 0x04, 0xE0, 0x02, 0x99, 0x07, 0x22, 0xF9, 0xF7, 0x6F, 0xFF, 0xFF, 0x1D, 0x07, 0xF8, 0x01, 0x4B, 0x15, 0x3C, 0x15, 0x21, 0x28, 0x78, 0xE2, 0xB2, 0x5B, 0x46, 0x07, 0xF8, 0x01, 0x1B, 0x32, 0x54, 0x07, 0xF8, 0x01, 0x9B, 0x38, 0x46, 0x00, 0xF0, 0x8B, 0xF9, 0x28, 0x78, 0x31, 0x5C, 0x0A, 0x31, 0x31, 0x54, 0x40, 0x1C, 0x28, 0x70, 0xBD, 0xE8, 0xFE, 0x8F, 0xC0, 0x46 ,
0x54, 0x54, 0x54, 0x4B, 0x45, 0x59, 0x00, 0xC0, 0x54, 0x54, 0x54, 0x53, 0x53, 0x49, 0x44, 0x00, 0x54, 0x58, 0x02, 0x00, 0xE6, 0x58, 0x02, 0x00, 0xE8, 0x58, 0x02, 0x00, 0x5C, 0x58, 0x02, 0x00, 0x5C, 0x57, 0x02, 0x00, 0xDC, 0x58, 0x02, 0x00, 0xD4, 0x57, 0x02, 0x00, 0x94, 0x57, 0x02, 0x00, 0xFF, 0xB5, 0x0C, 0x46, 0x06, 0x46, 0xF7, 0xF7, 0x4C, 0x5A, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xE3, 0xFE, 0x15, 0x49, 0x15, 0x4A, 0x0D, 0x68, 0x01, 0xA9, 0x92, 0xE8, 0x8C, 0x00, 0x81, 0xE8, 0x8C, 0x00, 0xF7, 0xF7, 0xFD, 0xFE, 0x01, 0x98, 0x11, 0x49, 0x28, 0x1A, 0x03, 0x9D, 0x25, 0x60, 0x02, 0x9A, 0x80, 0x18, 0x82, 0x42, 0x30, 0x60, 0x0E, 0xD8, 0x08, 0x46, 0x00, 0x68, 0x22, 0x68, 0x82, 0x42, 0x0E, 0xD2, 0x68, 0x46, 0xE8, 0xF7, 0xB9, 0xFF, 0x9D, 0xF8, 0x00, 0x00, 0x05, 0xF1, 0x01, 0x05, 0x30, 0xB9, 0x03, 0x95, 0x03, 0xE0, 0x25, 0x68, 0x6D, 0x1C, 0x25, 0x60, 0x0C, 0x46, 0x25, 0x60, 0x00, 0x20, 0x00, 0x90 ,
0xFF, 0xBD, 0x60, 0x55, 0x30, 0x80, 0x24, 0x5D, 0x00, 0x20, 0x6C, 0x5D, 0x02, 0x00, 0x70, 0xB5, 0x4D, 0x00, 0x20, 0x2D, 0x4F, 0xF0, 0x00, 0x01, 0x0C, 0x46, 0x4F, 0xEA, 0x55, 0x13, 0x09, 0xD3, 0x50, 0xF8, 0x21, 0x60, 0xB6, 0xF1, 0xFF, 0x3F, 0x04, 0xD1, 0x49, 0x1C, 0xC9, 0xB2, 0x20, 0x3D, 0x5B, 0x1E, 0xF5, 0xD1, 0x4D, 0xB1, 0x20, 0x2D, 0x09, 0xD2, 0x01, 0x23, 0xAB, 0x40, 0x5B, 0x1E, 0x50, 0xF8, 0x21, 0x00, 0x18, 0x40, 0x83, 0x42, 0x01, 0xD1, 0x4F, 0xF0, 0x01, 0x04, 0x07, 0x48, 0x03, 0x78, 0x2C, 0xB9, 0x01, 0x21, 0x91, 0x40, 0xC9, 0x43, 0xC9, 0xB2, 0x0B, 0x40, 0x03, 0xE0, 0x01, 0x21, 0x91, 0x40, 0xC9, 0xB2, 0x0B, 0x43, 0x03, 0x70, 0x70, 0xBD, 0xC0, 0x46, 0xEE, 0x58, 0x02, 0x00, 0x14, 0x5B, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x7E, 0xB5, 0x05, 0x46, 0x95, 0xF8, 0x36, 0x20, 0x0E, 0x46, 0x0F, 0x49, 0x07, 0x2A, 0x12, 0xBF, 0x08, 0x68, 0x01, 0x20, 0x08, 0x60, 0x0D, 0x4C, 0x00, 0x92, 0x21, 0x68 ,
0x41, 0xF2, 0x12, 0x13, 0x04, 0x22, 0x01, 0x91, 0x07, 0x21, 0x02, 0x90, 0x03, 0x20, 0xF2, 0xF7, 0x6B, 0xFD, 0x31, 0x46, 0x28, 0x46, 0xE7, 0xF7, 0x21, 0xFC, 0x21, 0x68, 0x00, 0x22, 0x05, 0x29, 0x02, 0xD1, 0x04, 0x49, 0x08, 0x31, 0x0A, 0x60, 0x7E, 0xBD, 0xC0, 0x46, 0x50, 0x57, 0x02, 0x00, 0x4C, 0x57, 0x02, 0x00, 0x00, 0x7C, 0x00, 0x20, 0x0E, 0x49, 0x09, 0x68, 0x49, 0x08, 0x15, 0xD2, 0x0D, 0x49, 0x09, 0x78, 0x91, 0xB1, 0x44, 0xF2, 0xE9, 0x21, 0x68, 0xB9, 0x0B, 0x48, 0x01, 0x78, 0x07, 0x48, 0x01, 0x29, 0x03, 0xD1, 0x0A, 0x49, 0x09, 0x78, 0x0E, 0x29, 0x02, 0xD0, 0x44, 0xF2, 0xDE, 0x21, 0x41, 0x60, 0x01, 0x21, 0x00, 0xE0, 0x06, 0x48, 0x01, 0x60, 0x70, 0x47, 0xC0, 0x46, 0x00, 0x97, 0x3C, 0x80, 0x10, 0x0C, 0x30, 0x80, 0xDD, 0x6A, 0x00, 0x20, 0xE0, 0x7C, 0x00, 0x20, 0xA6, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x00, 0xB5, 0xAD, 0xF1, 0x18, 0x0D, 0x4F, 0xF0, 0x09, 0x00, 0x00, 0x90, 0x4F, 0xF4 ,
0x0C, 0x60, 0x03, 0x90, 0x4F, 0xF0, 0x00, 0x00, 0x01, 0x90, 0x02, 0x90, 0x08, 0x48, 0x08, 0x49, 0x05, 0x90, 0x08, 0x68, 0x20, 0xB9, 0xDC, 0x5B, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x68, 0x46, 0x03, 0x22, 0xED, 0xF7, 0x3A, 0xFA, 0x03, 0xE0, 0x68, 0x46, 0x03, 0x22, 0xED, 0xF7, 0xC1, 0xFC, 0x06, 0xB0, 0x00, 0xBD, 0xC0, 0x46, 0x81, 0x5C, 0x02, 0x00, 0xDC, 0x7C, 0x00, 0x20, 0x1C, 0xB5, 0x0F, 0x4C, 0x22, 0x68, 0x01, 0x2A, 0x15, 0xD1, 0x0C, 0x48, 0x00, 0x68, 0x07, 0x28, 0x14, 0xBF, 0x40, 0x20, 0x4F, 0xF4, 0x05, 0x70, 0x63, 0x21, 0xF1, 0xF7, 0x0F, 0xFA, 0x20, 0x68, 0x00, 0x90, 0x43, 0xF2, 0x33, 0x33, 0x06, 0x21, 0x40, 0x20, 0x01, 0x90, 0x03, 0x20, 0x02, 0x46, 0xF2, 0xF7, 0xF4, 0xFC, 0x1C, 0xBD, 0xF1, 0xF7, 0x01, 0xFA, 0x1C, 0xBD, 0x4C, 0x57, 0x02, 0x00, 0x50, 0x57, 0x02, 0x00, 0x1E, 0xB5, 0x04, 0x46, 0x0A, 0x49, 0x00, 0x20, 0x0A, 0x4A, 0x08, 0x60, 0x0A, 0x49, 0x00, 0x90, 0x01, 0x90, 0x11, 0x60 ,
0x09, 0x4A, 0x45, 0xF2, 0x55, 0x53, 0x02, 0x91, 0x10, 0x60, 0x07, 0x21, 0x04, 0x22, 0x03, 0x20, 0xF2, 0xF7, 0xD8, 0xFC, 0x20, 0x46, 0xE7, 0xF7, 0x59, 0xFD, 0x1E, 0xBD, 0x50, 0x57, 0x02, 0x00, 0x04, 0x74, 0x00, 0x20, 0x34, 0x12, 0x66, 0x09, 0x4C, 0x57, 0x02, 0x00, 0x00, 0xB5, 0x0B, 0x49, 0x00, 0x20, 0x08, 0x60, 0xE0, 0x20, 0xF7, 0xF7, 0xAA, 0xFD, 0x09, 0x49, 0x09, 0x78, 0x49, 0xB1, 0x08, 0x49, 0x0A, 0x78, 0x08, 0x49, 0x00, 0x2A, 0x06, 0xBF, 0x01, 0x22, 0x09, 0x1F, 0x44, 0xF2, 0xA4, 0x5C, 0x02, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xE9, 0x22, 0x0A, 0x60, 0xF7, 0xF7, 0xA1, 0xFD, 0x00, 0xBD, 0xC0, 0x46, 0xDC, 0x7C, 0x00, 0x20, 0xDD, 0x6A, 0x00, 0x20, 0xA7, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x50, 0xB9, 0x09, 0x48, 0x00, 0x78, 0x01, 0x28, 0x06, 0xD1, 0x08, 0x48, 0x00, 0x78, 0x0E, 0x28, 0x08, 0xBF, 0x44, 0xF2, 0xCB, 0x20, 0x01, 0xD0, 0x44, 0xF2, 0xDE, 0x20, 0x04, 0x49, 0x08, 0x60, 0x01, 0x20 ,
0x41, 0xF8, 0x04, 0x0C, 0x70, 0x47, 0xE0, 0x7C, 0x00, 0x20, 0xA6, 0x64, 0x00, 0x20, 0x04, 0x97, 0x3C, 0x80, 0x30, 0xB5, 0x0D, 0x46, 0x84, 0x69, 0xDC, 0xF7, 0x97, 0xFB, 0x24, 0x1D, 0x01, 0x28, 0x04, 0xEB, 0x45, 0x01, 0x06, 0xD1, 0x89, 0x8E, 0x04, 0xEB, 0x85, 0x04, 0x11, 0xB9, 0x21, 0x69, 0x01, 0xB9, 0x00, 0x20, 0x30, 0xBD, 0x30, 0xB5, 0x05, 0x46, 0x5A, 0xB1, 0x03, 0xEB, 0x41, 0x03, 0x1C, 0x78, 0x59, 0x78, 0x41, 0xEA, 0x04, 0x11, 0x52, 0x1E, 0x03, 0xF1, 0x02, 0x03, 0x05, 0xF8, 0x01, 0x1B, 0xF5, 0xD1, 0x30, 0xBD, 0x00, 0xB5, 0x00, 0x20, 0xE7, 0xF7, 0xD6, 0xFE, 0x03, 0x48, 0x01, 0x68, 0x03, 0x29, 0x04, 0xBF, 0x04, 0x21, 0x01, 0x60, 0x00, 0xBD, 0xC0, 0x46, 0x4C, 0x57, 0x02, 0x00, 0x03, 0x4A, 0x12, 0x68, 0x01, 0x2A, 0x04, 0xBF, 0x02, 0x48, 0x63, 0x21, 0xF1, 0xF7, 0x76, 0xB9, 0x50, 0x57, 0x02, 0x00, 0x02, 0x20, 0x01, 0x00, 0x6C, 0x5D, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -0,0 +1,414 @@
#include <stdio.h>
#include <string.h>
#include "cc3000_common.h"
#include "nvmem.h"
#include "ccspi.h"
#include "hci.h"
#include "wlan.h"
#include "patch_prog.h"
#define BIT0 0x1
#define BIT1 0x2
#define BIT2 0x4
#define BIT3 0x8
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
static unsigned char ucStatus_Dr;
static unsigned char ucStatus_FW;
static unsigned char return_status = 0xFF;
static signed char mac_status = -1;
static unsigned char counter = 0;
// Array to store RM parameters from EEPROM.
static unsigned char cRMParamsFromEeprom[128];
// Array to store MAC address from EEPROM.
static unsigned char cMacFromEeprom[MAC_ADDR_LEN];
// Smart Config Prefix
static const char aucCC3000_prefix[] = {'T', 'T', 'T'};
static void systick_sleep(unsigned long ms) {
extern void HAL_Delay(volatile uint32_t Delay);
HAL_Delay(ms);
}
// 2 dim array to store address and length of new FAT
static const unsigned short aFATEntries[2][NVMEM_RM_FILEID + 1] =
/* address */ {{0x50, 0x1f0, 0x390, 0x1390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830},
/* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200}};
/* 0. NVS */
/* 1. NVS Shadow */
/* 2. Wireless Conf */
/* 3. Wireless Conf Shadow */
/* 4. BT (WLAN driver) Patches */
/* 5. WiLink (Firmware) Patches */
/* 6. MAC addr */
/* 7. Frontend Vars */
/* 8. IP config */
/* 9. IP config Shadow */
/* 10. Bootloader Patches */
/* 11. Radio Module params */
/* 12. AES128 for smart config */
/* 13. user file */
/* 14. user file */
/* 15. user file */
//*****************************************************************************
//
//! sendDriverPatch
//!
//! \param pointer to the length
//!
//! \return none
//!
//! \brief The function returns a pointer to the driver patch:
//! since there is no patch yet - it returns 0
//
//*****************************************************************************
static char *sendDriverPatch(unsigned long *Length)
{
*Length = 0;
return NULL;
}
//*****************************************************************************
//
//! sendBootLoaderPatch
//!
//! \param pointer to the length
//!
//! \return none
//!
//! \brief The function returns a pointer to the boot loader patch:
//! since there is no patch yet - it returns 0
//
//*****************************************************************************
static char *sendBootLoaderPatch(unsigned long *Length)
{
*Length = 0;
return NULL;
}
//*****************************************************************************
//
//! sendWLFWPatch
//!
//! \param pointer to the length
//!
//! \return none
//!
//! \brief The function returns a pointer to the FW patch:
//! since there is no patch yet - it returns 0
//
//*****************************************************************************
static char *sendWLFWPatch(unsigned long *Length)
{
*Length = 0;
return NULL;
}
//*****************************************************************************
//
//! CC3000_UsynchCallback
//!
//! \param Event type
//!
//! \return none
//!
//! \brief The function handles asynchronous events that come from CC3000
//! device and operates a LED4 to have an on-board indication
//
//*****************************************************************************
static void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
{
}
//*****************************************************************************
//
//! initDriver
//!
//! \param[in] cRequestPatch 0 to load with EEPROM patches
//! and 1 to load with no patches
//!
//! \return none
//!
//! \brief The function initializes a CC3000 device
//! and triggers it to start operation
//
//*****************************************************************************
static int initDriver(unsigned short cRequestPatch)
{
// WLAN On API Implementation
wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch,
ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin);
// Trigger a WLAN device
wlan_start(cRequestPatch);
wlan_smart_config_set_prefix((char*)aucCC3000_prefix);
wlan_ioctl_set_connection_policy(0, 0, 0);
wlan_ioctl_del_profile(255);
// Mask out all non-required events from CC3000
wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|
HCI_EVNT_WLAN_UNSOL_INIT|
HCI_EVNT_WLAN_ASYNC_PING_REPORT);
//unsolicicted_events_timer_init();
systick_sleep(100);
return(0);
}
//*****************************************************************************
//
//! fat_read_content
//!
//! \param[out] is_allocated array of is_allocated in FAT table:\n
//! an allocated entry implies the address and length of the
//! file are valid.
//! 0: not allocated; 1: allocated.
//! \param[out] is_valid array of is_valid in FAT table:\n
//! a valid entry implies the content of the file is relevant.
//! 0: not valid; 1: valid.
//! \param[out] write_protected array of write_protected in FAT table:\n
//! a write protected entry implies it is not possible to write
//! into this entry.
//! 0: not protected; 1: protected.
//! \param[out] file_address array of file address in FAT table:\n
//! this is the absolute address of the file in the EEPROM.
//! \param[out] file_length array of file length in FAT table:\n
//! this is the upper limit of the file size in the EEPROM.
//!
//! \return on succes 0, error otherwise
//!
//! \brief parse the FAT table from eeprom
//
//*****************************************************************************
static unsigned char __attribute__ ((unused))
fat_read_content(unsigned char *is_allocated, unsigned char *is_valid,
unsigned char *write_protected, unsigned short *file_address, unsigned short *file_length)
{
unsigned short index;
unsigned char ucStatus;
unsigned char fatTable[48];
unsigned char* fatTablePtr = fatTable;
//
// Read in 6 parts to work with tiny driver
//
for (index = 0; index < 6; index++)
{
ucStatus = nvmem_read(16, 8, 4 + 8*index, fatTablePtr);
fatTablePtr += 8;
}
fatTablePtr = fatTable;
for (index = 0; index <= NVMEM_RM_FILEID; index++)
{
*is_allocated++ = (*fatTablePtr) & BIT0;
*is_valid++ = ((*fatTablePtr) & BIT1) >> 1;
*write_protected++ = ((*fatTablePtr) & BIT2) >> 2;
*file_address++ = ((*(fatTablePtr+1)<<8) | (*fatTablePtr)) & (BIT4|BIT5|BIT6|BIT7);
*file_length++ = ((*(fatTablePtr+3)<<8) | (*(fatTablePtr+2))) & (BIT4|BIT5|BIT6|BIT7);
//
// Move to next file ID
//
fatTablePtr += 4;
}
return ucStatus;
}
//*****************************************************************************
//
//! fat_write_content
//!
//! \param[in] file_address array of file address in FAT table:\n
//! this is the absolute address of the file in the EEPROM.
//! \param[in] file_length array of file length in FAT table:\n
//! this is the upper limit of the file size in the EEPROM.
//!
//! \return on succes 0, error otherwise
//!
//! \brief parse the FAT table from eeprom
//
//*****************************************************************************
static unsigned char fat_write_content(unsigned short const *file_address,
unsigned short const *file_length)
{
unsigned short index = 0;
unsigned char ucStatus;
unsigned char fatTable[48];
unsigned char* fatTablePtr = fatTable;
//
// First, write the magic number.
//
ucStatus = nvmem_write(16, 2, 0, (unsigned char*)"LS");
for (; index <= NVMEM_RM_FILEID; index++)
{
//
// Write address low char and mark as allocated.
//
*fatTablePtr++ = (unsigned char)(file_address[index] & 0xff) | BIT0;
//
// Write address high char.
//
*fatTablePtr++ = (unsigned char)((file_address[index]>>8) & 0xff);
//
// Write length low char.
//
*fatTablePtr++ = (unsigned char)(file_length[index] & 0xff);
//
// Write length high char.
//
*fatTablePtr++ = (unsigned char)((file_length[index]>>8) & 0xff);
}
//
// Second, write the FAT.
// Write in two parts to work with tiny driver.
//
ucStatus = nvmem_write(16, 24, 4, fatTable);
ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]);
//
// Third, we want to erase any user files.
//
memset(fatTable, 0, sizeof(fatTable));
ucStatus = nvmem_write(16, 16, 52, fatTable);
return ucStatus;
}
void patch_prog_start()
{
unsigned short index;
unsigned char *pRMParams;
printf("Initializing module...\n");
// Init module and request to load with no patches.
// This is in order to overwrite restrictions to
// write to specific places in EEPROM.
initDriver(1);
// Read MAC address.
mac_status = nvmem_get_mac_address(cMacFromEeprom);
return_status = 1;
printf("Reading RM parameters...\n");
while ((return_status) && (counter < 3)) {
// Read RM parameters.
// Read in 16 parts to work with tiny driver.
return_status = 0;
pRMParams = cRMParamsFromEeprom;
for (index = 0; index < 16; index++) {
return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams);
pRMParams += 8;
}
counter++;
}
// If RM file is not valid, load the default one.
if (counter == 3) {
printf("RM is not valid, loading default one...\n");
pRMParams = (unsigned char *)cRMdefaultParams;
} else {
printf("RM is valid.\n");
pRMParams = cRMParamsFromEeprom;
}
return_status = 1;
printf("Writing new FAT\n");
while (return_status) {
// Write new FAT.
return_status = fat_write_content(aFATEntries[0], aFATEntries[1]);
}
return_status = 1;
printf("Writing RM parameters...\n");
while (return_status) {
// Write RM parameters.
// Write in 4 parts to work with tiny driver.
return_status = 0;
for (index = 0; index < 4; index++) {
return_status |= nvmem_write(NVMEM_RM_FILEID,
32,
32*index,
(pRMParams + 32*index));
}
}
return_status = 1;
// Write back the MAC address, only if exists.
if (mac_status == 0) {
// Zero out MCAST bit if set.
cMacFromEeprom[0] &= 0xfe;
printf("Writing back MAC address..\n");
while (return_status) {
return_status = nvmem_set_mac_address(cMacFromEeprom);
}
}
// Update driver
ucStatus_Dr = 1;
printf("Updating driver patch...\n");
while (ucStatus_Dr) {
// Writing driver patch to EEPRROM - PROTABLE CODE
// Note that the array itself is changing between the
// different Service Packs.
ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID,
drv_length,
wlan_drv_patch);
}
// Update firmware
ucStatus_FW = 1;
printf("Updating firmware patch...\n");
while (ucStatus_FW) {
// Writing FW patch to EEPRROM - PROTABLE CODE
// Note that the array itself is changing between the
// different Service Packs.
ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID,
fw_length,
fw_patch);
}
printf("Update complete, resetting module\n"\
"If this doesn't work, reset manually...\n");
wlan_stop();
systick_sleep(500);
// Re-Init module and request to load with patches.
initDriver(0);
// If MAC does not exist, it is recommended
// that the user will write a valid mac address.
if (mac_status != 0) {
printf("MAC address is not valid, please write a new one\n");
}
// Patch update done
printf("All done, call wlan.patch_version()\n");
}

View File

@@ -12,23 +12,23 @@
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
@@ -40,16 +40,11 @@
//
//*****************************************************************************
#include <stdint.h>
#include "mpconfigport.h"
#if MICROPY_HW_ENABLE_CC3K
#include "security.h"
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
// foreward sbox
const unsigned char sbox[256] = {
const UINT8 sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
@@ -66,9 +61,9 @@ const unsigned char sbox[256] = {
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
// inverse sbox
const unsigned char rsbox[256] =
const UINT8 rsbox[256] =
{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
@@ -86,11 +81,11 @@ const unsigned char rsbox[256] =
, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// round constant
const unsigned char Rcon[11] = {
const UINT8 Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
unsigned char expandedKey[176];
UINT8 expandedKey[176];
//*****************************************************************************
//
@@ -105,10 +100,9 @@ unsigned char expandedKey[176];
//!
//*****************************************************************************
void expandKey(unsigned char *expandedKey,
unsigned char *key)
void expandKey(UINT8 *expandedKey, UINT8 *key)
{
unsigned short ii, buf1;
UINT16 ii, buf1;
for (ii=0;ii<16;ii++)
expandedKey[ii] = key[ii];
for (ii=1;ii<11;ii++){
@@ -130,7 +124,7 @@ void expandKey(unsigned char *expandedKey,
expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10];
expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11];
}
}
//*****************************************************************************
@@ -145,7 +139,7 @@ void expandKey(unsigned char *expandedKey,
//!
//*****************************************************************************
unsigned char galois_mul2(unsigned char value)
UINT8 galois_mul2(UINT8 value)
{
if (value>>7)
{
@@ -171,18 +165,18 @@ unsigned char galois_mul2(unsigned char value)
//! - subbytes
//! - shiftrows
//! - mixcolums
//! is executed 9 times, after this addroundkey to finish the 9th
//! is executed 9 times, after this addroundkey to finish the 9th
//! round, after that the 10th round without mixcolums
//! no further subfunctions to save cycles for function calls
//! no structuring with "for (....)" to save cycles.
//!
//!
//!
//*****************************************************************************
void aes_encr(unsigned char *state, unsigned char *expandedKey)
void aes_encr(UINT8 *state, UINT8 *expandedKey)
{
unsigned char buf1, buf2, buf3, round;
UINT8 buf1, buf2, buf3, round;
for (round = 0; round < 9; round ++){
// addroundkey, sbox and shiftrows
// row 0
@@ -209,7 +203,7 @@ void aes_encr(unsigned char *state, unsigned char *expandedKey)
state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])];
state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])];
state[ 3] = sbox[buf1];
// mixcolums //////////
// col1
buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
@@ -238,8 +232,8 @@ void aes_encr(unsigned char *state, unsigned char *expandedKey)
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
}
// 10th round without mixcols
state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])];
@@ -280,9 +274,9 @@ void aes_encr(unsigned char *state, unsigned char *expandedKey)
state[11]^=expandedKey[171];
state[12]^=expandedKey[172];
state[13]^=expandedKey[173];
state[14]^=expandedKey[174];
state[14]^=expandedKey[174];
state[15]^=expandedKey[175];
}
}
//*****************************************************************************
//
@@ -306,12 +300,12 @@ void aes_encr(unsigned char *state, unsigned char *expandedKey)
//!
//*****************************************************************************
void aes_decr(unsigned char *state, unsigned char *expandedKey)
void aes_decr(UINT8 *state, UINT8 *expandedKey)
{
unsigned char buf1, buf2, buf3;
signed char round;
UINT8 buf1, buf2, buf3;
INT8 round;
round = 9;
// initial addroundkey
state[ 0]^=expandedKey[160];
state[ 1]^=expandedKey[161];
@@ -327,9 +321,9 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey)
state[11]^=expandedKey[171];
state[12]^=expandedKey[172];
state[13]^=expandedKey[173];
state[14]^=expandedKey[174];
state[14]^=expandedKey[174];
state[15]^=expandedKey[175];
// 10th round without mixcols
state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4];
@@ -354,7 +348,7 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey)
state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7];
state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
state[15] = buf1;
for (round = 8; round >= 0; round--){
// barreto
//col1
@@ -401,8 +395,8 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey)
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
// addroundkey, rsbox and shiftrows
// row 0
state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
@@ -429,8 +423,8 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey)
state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
state[15] = buf1;
}
}
}
//*****************************************************************************
//
@@ -443,17 +437,16 @@ void aes_decr(unsigned char *state, unsigned char *expandedKey)
//!
//! @brief AES128 encryption:
//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
//! is computed. The AES implementation is in mode ECB (Electronic
//! Code Book).
//!
//! is computed. The AES implementation is in mode ECB (Electronic
//! Code Book).
//!
//!
//*****************************************************************************
void aes_encrypt(unsigned char *state,
unsigned char *key)
void aes_encrypt(UINT8 *state, UINT8 *key)
{
// expand the key into 176 bytes
expandKey(expandedKey, key);
expandKey(expandedKey, key);
aes_encr(state, expandedKey);
}
@@ -468,14 +461,13 @@ void aes_encrypt(unsigned char *state,
//!
//! @brief AES128 decryption:
//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
//! is computed The AES implementation is in mode ECB
//! is computed The AES implementation is in mode ECB
//! (Electronic Code Book).
//!
//!
//!
//*****************************************************************************
void aes_decrypt(unsigned char *state,
unsigned char *key)
void aes_decrypt(UINT8 *state, UINT8 *key)
{
expandKey(expandedKey, key); // expand the key into 176 bytes
aes_decr(state, expandedKey);
@@ -491,15 +483,15 @@ void aes_decrypt(unsigned char *state,
//!
//! @brief Reads AES128 key from EEPROM
//! Reads the AES128 key from fileID #12 in EEPROM
//! returns an error if the key does not exist.
//!
//! returns an error if the key does not exist.
//!
//!
//*****************************************************************************
signed long aes_read_key(unsigned char *key)
INT32 aes_read_key(UINT8 *key)
{
signed long returnValue;
INT32 returnValue;
returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
return returnValue;
@@ -515,13 +507,13 @@ signed long aes_read_key(unsigned char *key)
//!
//! @brief writes AES128 key from EEPROM
//! Writes the AES128 key to fileID #12 in EEPROM
//!
//!
//!
//*****************************************************************************
signed long aes_write_key(unsigned char *key)
INT32 aes_write_key(UINT8 *key)
{
signed long returnValue;
INT32 returnValue;
returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
@@ -536,5 +528,3 @@ signed long aes_write_key(unsigned char *key)
//! @}
//
//*****************************************************************************
#endif // MICROPY_HW_ENABLE_CC3K

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,234 @@
"""NRF24L01 driver for Micro Python"""
import pyb
# nRF24L01+ registers
CONFIG = const(0x00)
EN_RXADDR = const(0x02)
SETUP_AW = const(0x03)
SETUP_RETR = const(0x04)
RF_CH = const(0x05)
RF_SETUP = const(0x06)
STATUS = const(0x07)
OBSERVE_TX = const(0x08)
RX_ADDR_P0 = const(0x0a)
TX_ADDR = const(0x10)
RX_PW_P0 = const(0x11)
FIFO_STATUS = const(0x17)
DYNPD = const(0x1c)
# CONFIG register
EN_CRC = const(0x08) # enable CRC
CRCO = const(0x04) # CRC encoding scheme; 0=1 byte, 1=2 bytes
PWR_UP = const(0x02) # 1=power up, 0=power down
PRIM_RX = const(0x01) # RX/TX control; 0=PTX, 1=PRX
# RF_SETUP register
POWER_0 = const(0x00) # -18 dBm
POWER_1 = const(0x02) # -12 dBm
POWER_2 = const(0x04) # -6 dBm
POWER_3 = const(0x06) # 0 dBm
SPEED_1M = const(0x00)
SPEED_2M = const(0x08)
SPEED_250K = const(0x20)
# STATUS register
RX_DR = const(0x40) # RX data ready; write 1 to clear
TX_DS = const(0x20) # TX data sent; write 1 to clear
MAX_RT = const(0x10) # max retransmits reached; write 1 to clear
# FIFO_STATUS register
RX_EMPTY = const(0x01) # 1 if RX FIFO is empty
# constants for instructions
R_RX_PL_WID = const(0x60) # read RX payload width
R_RX_PAYLOAD = const(0x61) # read RX payload
W_TX_PAYLOAD = const(0xa0) # write TX payload
FLUSH_TX = const(0xe1) # flush TX FIFO
FLUSH_RX = const(0xe2) # flush RX FIFO
NOP = const(0xff) # use to read STATUS register
class NRF24L01:
def __init__(self, spi, cs, ce, channel=46, payload_size=16):
assert payload_size <= 32
# init the SPI bus and pins
spi.init(spi.MASTER, baudrate=4000000, polarity=0, phase=1, firstbit=spi.MSB)
cs.init(cs.OUT_PP, cs.PULL_NONE)
ce.init(ce.OUT_PP, ce.PULL_NONE)
# store the pins
self.spi = spi
self.cs = cs
self.ce = ce
# reset everything
self.ce.low()
self.cs.high()
self.payload_size = payload_size
self.pipe0_read_addr = None
pyb.delay(5)
# set address width to 5 bytes
self.reg_write(SETUP_AW, 0b11)
# disable dynamic payloads
self.reg_write(DYNPD, 0)
# auto retransmit delay: 1750us
# auto retransmit count: 8
self.reg_write(SETUP_RETR, (6 << 4) | 8)
# set rf power and speed
self.set_power_speed(POWER_3, SPEED_1M)
# init CRC
self.set_crc(2)
# clear status flags
self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
# set channel
self.set_channel(channel)
# flush buffers
self.flush_rx()
self.flush_tx()
def reg_read(self, reg):
self.cs.low()
self.spi.send_recv(reg)
buf = self.spi.recv(1)
self.cs.high()
return buf[0]
def reg_read_ret_status(self, reg):
self.cs.low()
status = self.spi.send_recv(reg)[0]
buf = self.spi.recv(1)
self.cs.high()
return status
def reg_write(self, reg, buf):
self.cs.low()
status = self.spi.send_recv(0x20 | reg)[0]
self.spi.send(buf)
self.cs.high()
return status
def flush_rx(self):
self.cs.low()
self.spi.send(FLUSH_RX)
self.cs.high()
def flush_tx(self):
self.cs.low()
self.spi.send(FLUSH_TX)
self.cs.high()
# power is one of POWER_x defines; speed is one of SPEED_x defines
def set_power_speed(self, power, speed):
setup = self.reg_read(RF_SETUP) & 0b11010001
self.reg_write(RF_SETUP, setup | power | speed)
# length in bytes: 0, 1 or 2
def set_crc(self, length):
config = self.reg_read(CONFIG) & ~(CRCO | EN_CRC)
if length == 0:
pass
elif length == 1:
config |= EN_CRC
else:
config |= EN_CRC | CRCO
self.reg_write(CONFIG, config)
def set_channel(self, channel):
self.reg_write(RF_CH, min(channel, 127))
# address should be a bytes object 5 bytes long
def open_tx_pipe(self, address):
assert len(address) == 5
self.reg_write(RX_ADDR_P0, address)
self.reg_write(TX_ADDR, address)
self.reg_write(RX_PW_P0, self.payload_size)
# address should be a bytes object 5 bytes long
# pipe 0 and 1 have 5 byte address
# pipes 2-5 use same 4 most-significant bytes as pipe 1, plus 1 extra byte
def open_rx_pipe(self, pipe_id, address):
assert len(address) == 5
assert 0 <= pipe_id <= 5
if pipe_id == 0:
self.pipe0_read_addr = address
if pipe_id < 2:
self.reg_write(RX_ADDR_P0 + pipe_id, address)
else:
self.reg_write(RX_ADDR_P0 + pipe_id, address[0])
self.reg_write(RX_PW_P0 + pipe_id, self.payload_size)
self.reg_write(EN_RXADDR, self.reg_read(EN_RXADDR) | (1 << pipe_id))
def start_listening(self):
self.reg_write(CONFIG, self.reg_read(CONFIG) | PWR_UP | PRIM_RX)
self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
if self.pipe0_read_addr is not None:
self.reg_write(RX_ADDR_P0, self.pipe0_read_addr)
self.flush_rx()
self.flush_tx()
self.ce.high()
pyb.udelay(130)
def stop_listening(self):
self.ce.low()
self.flush_tx()
self.flush_rx()
# returns True if any data available to recv
def any(self):
return not bool(self.reg_read(FIFO_STATUS) & RX_EMPTY)
def recv(self):
# get the data
self.cs.low()
self.spi.send(R_RX_PAYLOAD)
buf = self.spi.recv(self.payload_size)
self.cs.high()
# clear RX ready flag
self.reg_write(STATUS, RX_DR)
return buf
def send(self, buf, timeout=500):
# power up
self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX)
pyb.udelay(150)
# send the data
self.cs.low()
self.spi.send(W_TX_PAYLOAD)
self.spi.send(buf)
if len(buf) < self.payload_size:
self.spi.send(b'\x00' * (self.payload_size - len(buf))) # pad out data
self.cs.high()
# enable the chip so it can send the data
self.ce.high()
pyb.udelay(15) # needs to be >10us
self.ce.low()
# blocking wait for tx complete
start = pyb.millis()
while pyb.millis() - start < timeout:
status = self.reg_read_ret_status(OBSERVE_TX)
if status & (TX_DS | MAX_RT):
break
# get and clear all status flags
status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
if not (status & TX_DS):
raise OSError("send failed")
# power down
self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP)

View File

@@ -0,0 +1,100 @@
"""Test for nrf24l01 module."""
import struct
import pyb
from pyb import Pin, SPI
from nrf24l01 import NRF24L01
pipes = (b'\xf0\xf0\xf0\xf0\xe1', b'\xf0\xf0\xf0\xf0\xd2')
def master():
nrf = NRF24L01(SPI(2), Pin('Y5'), Pin('Y4'), payload_size=8)
nrf.open_tx_pipe(pipes[0])
nrf.open_rx_pipe(1, pipes[1])
nrf.start_listening()
num_needed = 16
num_successes = 0
num_failures = 0
led_state = 0
print('NRF24L01 master mode, sending %d packets...' % num_needed)
while num_successes < num_needed and num_failures < num_needed:
# stop listening and send packet
nrf.stop_listening()
millis = pyb.millis()
led_state = max(1, (led_state << 1) & 0x0f)
print('sending:', millis, led_state)
try:
nrf.send(struct.pack('ii', millis, led_state))
except OSError:
pass
# start listening again
nrf.start_listening()
# wait for response, with 250ms timeout
start_time = pyb.millis()
timeout = False
while not nrf.any() and not timeout:
if pyb.elapsed_millis(start_time) > 250:
timeout = True
if timeout:
print('failed, respones timed out')
num_failures += 1
else:
# recv packet
got_millis, = struct.unpack('i', nrf.recv())
# print response and round-trip delay
print('got response:', got_millis, '(delay', pyb.millis() - got_millis, 'ms)')
num_successes += 1
# delay then loop
pyb.delay(250)
print('master finished sending; succeses=%d, failures=%d' % (num_successes, num_failures))
def slave():
nrf = NRF24L01(SPI(2), Pin('Y5'), Pin('Y4'), payload_size=8)
nrf.open_tx_pipe(pipes[1])
nrf.open_rx_pipe(1, pipes[0])
nrf.start_listening()
print('NRF24L01 slave mode, waiting for packets... (ctrl-C to stop)')
while True:
pyb.wfi()
if nrf.any():
while nrf.any():
buf = nrf.recv()
millis, led_state = struct.unpack('ii', buf)
print('received:', millis, led_state)
for i in range(4):
if led_state & (1 << i):
pyb.LED(i + 1).on()
else:
pyb.LED(i + 1).off()
pyb.delay(15)
nrf.stop_listening()
try:
nrf.send(struct.pack('i', millis))
except OSError:
pass
print('sent response')
nrf.start_listening()
print('NRF24L01 test module loaded')
print('NRF24L01 pinout for test:')
print(' CE on Y4')
print(' CSN on Y5')
print(' SCK on Y6')
print(' MISO on Y7')
print(' MOSI on Y8')
print('run nrf24l01test.slave() on slave, then nrf24l01test.master() on master')

View File

@@ -0,0 +1,6 @@
This is the driver for the WIZnet5x00 series of Ethernet controllers.
Adapted for Micro Python.
Original source: https://github.com/Wiznet/W5500_EVB/tree/master/ioLibrary
Taken on: 30 August 2014

View File

@@ -0,0 +1,703 @@
//*****************************************************************************
//
//! \file socket.c
//! \brief SOCKET APIs Implements file.
//! \details SOCKET APIs like as Berkeley Socket APIs.
//! \version 1.0.3
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.3. Refer to M20140501
//! 1. Implicit type casting -> Explicit type casting.
//! 2. replace 0x01 with PACK_REMAINED in recvfrom()
//! 3. Validation a destination ip in connect() & sendto():
//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
//! Copy 4 byte addr value into temporary uint32 variable and then compares it.
//! <2013/12/20> V1.0.2 Refer to M20131220
//! Remove Warning.
//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include "socket.h"
extern void HAL_Delay(uint32_t);
#define SOCK_ANY_PORT_NUM 0xC000;
static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
static uint16_t sock_io_mode = 0;
static uint16_t sock_is_sending = 0;
static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
#if _WIZCHIP_ == 5200
static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
#endif
#define CHECK_SOCKNUM() \
do{ \
if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
}while(0); \
#define CHECK_SOCKMODE(mode) \
do{ \
if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
}while(0); \
#define CHECK_SOCKINIT() \
do{ \
if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
}while(0); \
#define CHECK_SOCKDATA() \
do{ \
if(len == 0) return SOCKERR_DATALEN; \
}while(0); \
int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
{
CHECK_SOCKNUM();
switch(protocol)
{
case Sn_MR_TCP :
case Sn_MR_UDP :
case Sn_MR_MACRAW :
break;
#if ( _WIZCHIP_ < 5200 )
case Sn_MR_IPRAW :
case Sn_MR_PPPoE :
break;
#endif
default :
return SOCKERR_SOCKMODE;
}
if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
#if _WIZCHIP_ == 5200
if(flag & 0x10) return SOCKERR_SOCKFLAG;
#endif
if(flag != 0)
{
switch(protocol)
{
case Sn_MR_TCP:
if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
break;
case Sn_MR_UDP:
if(flag & SF_IGMP_VER2)
{
if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
}
#if _WIZCHIP_ == 5500
if(flag & SF_UNI_BLOCK)
{
if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
}
#endif
break;
default:
break;
}
}
WIZCHIP_EXPORT(close)(sn);
setSn_MR(sn, (protocol | (flag & 0xF0)));
if(!port)
{
port = sock_any_port++;
if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
}
setSn_PORT(sn,port);
setSn_CR(sn,Sn_CR_OPEN);
while(getSn_CR(sn));
sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
sock_is_sending &= ~(1<<sn);
sock_remained_size[sn] = 0;
sock_pack_info[sn] = 0;
while(getSn_SR(sn) == SOCK_CLOSED);
return (int8_t)sn;
}
int8_t WIZCHIP_EXPORT(close)(uint8_t sn)
{
CHECK_SOCKNUM();
setSn_CR(sn,Sn_CR_CLOSE);
/* wait to process the command... */
while( getSn_CR(sn) );
/* clear all interrupt of the socket. */
setSn_IR(sn, 0xFF);
sock_is_sending &= ~(1<<sn);
sock_remained_size[sn] = 0;
sock_pack_info[sn] = 0;
while(getSn_SR(sn) != SOCK_CLOSED);
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(listen)(uint8_t sn)
{
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKINIT();
setSn_CR(sn,Sn_CR_LISTEN);
while(getSn_CR(sn));
while(getSn_SR(sn) != SOCK_LISTEN)
{
if(getSn_CR(sn) == SOCK_CLOSED)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_SOCKCLOSED;
}
}
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(connect)(uint8_t sn, uint8_t * addr, uint16_t port)
{
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKINIT();
//M20140501 : For avoiding fatal error on memory align mismatched
//if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
{
uint32_t taddr;
taddr = ((uint32_t)addr[0] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
}
//
if(port == 0) return SOCKERR_PORTZERO;
setSn_DIPR(sn,addr);
setSn_DPORT(sn,port);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR(wizchip_getsubn());
#endif
setSn_CR(sn,Sn_CR_CONNECT);
while(getSn_CR(sn));
if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
while(getSn_SR(sn) != SOCK_ESTABLISHED)
{
if (getSn_SR(sn) == SOCK_CLOSED) {
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCKERR_SOCKCLOSED;
}
if (getSn_IR(sn) & Sn_IR_TIMEOUT)
{
setSn_IR(sn, Sn_IR_TIMEOUT);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCKERR_TIMEOUT;
}
HAL_Delay(1);
}
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(disconnect)(uint8_t sn)
{
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
setSn_CR(sn,Sn_CR_DISCON);
/* wait to process the command... */
while(getSn_CR(sn));
sock_is_sending &= ~(1<<sn);
if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
while(getSn_SR(sn) != SOCK_CLOSED)
{
if(getSn_IR(sn) & Sn_IR_TIMEOUT)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_TIMEOUT;
}
}
return SOCK_OK;
}
int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len)
{
uint8_t tmp=0;
uint16_t freesize=0;
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKDATA();
tmp = getSn_SR(sn);
if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
if( sock_is_sending & (1<<sn) )
{
tmp = getSn_IR(sn);
if(tmp & Sn_IR_SENDOK)
{
setSn_IR(sn, Sn_IR_SENDOK);
#if _WZICHIP_ == 5200
if(getSn_TX_RD(sn) != sock_next_rd[sn])
{
setSn_CR(sn,Sn_CR_SEND);
while(getSn_CR(sn));
return SOCKERR_BUSY;
}
#endif
sock_is_sending &= ~(1<<sn);
}
else if(tmp & Sn_IR_TIMEOUT)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_TIMEOUT;
}
else return SOCK_BUSY;
}
freesize = getSn_TxMAX(sn);
if (len > freesize) len = freesize; // check size not to exceed MAX size.
while(1)
{
freesize = getSn_TX_FSR(sn);
tmp = getSn_SR(sn);
if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_SOCKSTATUS;
}
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
if(len <= freesize) break;
}
wiz_send_data(sn, buf, len);
#if _WIZCHIP_ == 5200
sock_next_rd[sn] = getSn_TX_RD(sn) + len;
#endif
setSn_CR(sn,Sn_CR_SEND);
/* wait to process the command... */
while(getSn_CR(sn));
sock_is_sending |= (1 << sn);
return len;
}
int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len)
{
uint8_t tmp = 0;
uint16_t recvsize = 0;
CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKDATA();
recvsize = getSn_RxMAX(sn);
if(recvsize < len) len = recvsize;
while(1)
{
recvsize = getSn_RX_RSR(sn);
tmp = getSn_SR(sn);
if (tmp != SOCK_ESTABLISHED)
{
if(tmp == SOCK_CLOSE_WAIT)
{
if(recvsize != 0) break;
else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_SOCKSTATUS;
}
}
else
{
WIZCHIP_EXPORT(close)(sn);
return SOCKERR_SOCKSTATUS;
}
}
if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
if(recvsize != 0) break;
HAL_Delay(1);
};
if(recvsize < len) len = recvsize;
wiz_recv_data(sn, buf, len);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
return len;
}
int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
{
uint8_t tmp = 0;
uint16_t freesize = 0;
CHECK_SOCKNUM();
switch(getSn_MR(sn) & 0x0F)
{
case Sn_MR_UDP:
case Sn_MR_MACRAW:
break;
default:
return SOCKERR_SOCKMODE;
}
CHECK_SOCKDATA();
//M20140501 : For avoiding fatal error on memory align mismatched
//if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
{
uint32_t taddr;
taddr = ((uint32_t)addr[0]) & 0x000000FF;
taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
}
//
if(port == 0) return SOCKERR_PORTZERO;
tmp = getSn_SR(sn);
if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
setSn_DIPR(sn,addr);
setSn_DPORT(sn,port);
freesize = getSn_TxMAX(sn);
if (len > freesize) len = freesize; // check size not to exceed MAX size.
while(1)
{
freesize = getSn_TX_FSR(sn);
if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
if(len <= freesize) break;
HAL_Delay(1);
};
wiz_send_data(sn, buf, len);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR(wizchip_getsubn());
#endif
setSn_CR(sn,Sn_CR_SEND);
/* wait to process the command... */
while(getSn_CR(sn));
while(1)
{
tmp = getSn_IR(sn);
if(tmp & Sn_IR_SENDOK)
{
setSn_IR(sn, Sn_IR_SENDOK);
break;
}
//M:20131104
//else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
else if(tmp & Sn_IR_TIMEOUT)
{
setSn_IR(sn, Sn_IR_TIMEOUT);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCKERR_TIMEOUT;
}
////////////
HAL_Delay(1);
}
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return len;
}
int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
{
uint8_t mr;
uint8_t head[8];
uint16_t pack_len=0;
CHECK_SOCKNUM();
//CHECK_SOCKMODE(Sn_MR_UDP);
switch((mr=getSn_MR(sn)) & 0x0F)
{
case Sn_MR_UDP:
case Sn_MR_MACRAW:
break;
#if ( _WIZCHIP_ < 5200 )
case Sn_MR_IPRAW:
case Sn_MR_PPPoE:
break;
#endif
default:
return SOCKERR_SOCKMODE;
}
CHECK_SOCKDATA();
if(sock_remained_size[sn] == 0)
{
while(1)
{
pack_len = getSn_RX_RSR(sn);
if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
if(pack_len != 0) break;
};
}
sock_pack_info[sn] = PACK_COMPLETED;
switch (mr & 0x07)
{
case Sn_MR_UDP :
if(sock_remained_size[sn] == 0)
{
wiz_recv_data(sn, head, 8);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
// read peer's IP address, port number & packet length
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = head[4];
*port = (*port << 8) + head[5];
sock_remained_size[sn] = head[6];
sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
sock_pack_info[sn] = PACK_FIRST;
}
if(len < sock_remained_size[sn]) pack_len = len;
else pack_len = sock_remained_size[sn];
//
// Need to packet length check (default 1472)
//
wiz_recv_data(sn, buf, pack_len); // data copy.
break;
case Sn_MR_MACRAW :
if(sock_remained_size[sn] == 0)
{
wiz_recv_data(sn, head, 2);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
// read peer's IP address, port number & packet length
sock_remained_size[sn] = head[0];
sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
if(sock_remained_size[sn] > 1514)
{
WIZCHIP_EXPORT(close)(sn);
return SOCKFATAL_PACKLEN;
}
sock_pack_info[sn] = PACK_FIRST;
}
if(len < sock_remained_size[sn]) pack_len = len;
else pack_len = sock_remained_size[sn];
wiz_recv_data(sn,buf,pack_len);
break;
#if ( _WIZCHIP_ < 5200 )
case Sn_MR_IPRAW:
if(sock_remained_size[sn] == 0)
{
wiz_recv_data(sn, head, 6);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
sock_remained_size[sn] = head[4];
sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
sock_pack_info[sn] = PACK_FIRST;
}
//
// Need to packet length check
//
if(len < sock_remained_size[sn]) pack_len = len;
else pack_len = sock_remained_size[sn];
wiz_recv_data(sn, buf, pack_len); // data copy.
break;
#endif
default:
wiz_recv_ignore(sn, pack_len); // data copy.
sock_remained_size[sn] = pack_len;
break;
}
setSn_CR(sn,Sn_CR_RECV);
/* wait to process the command... */
while(getSn_CR(sn)) ;
sock_remained_size[sn] -= pack_len;
//M20140501 : replace 0x01 with PACK_REMAINED
//if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED;
//
return pack_len;
}
int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg)
{
uint8_t tmp = 0;
CHECK_SOCKNUM();
switch(cstype)
{
case CS_SET_IOMODE:
tmp = *((uint8_t*)arg);
if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn);
else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
else return SOCKERR_ARG;
break;
case CS_GET_IOMODE:
//M20140501 : implict type casting -> explict type casting
//*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
*((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
//
break;
case CS_GET_MAXTXBUF:
*((uint16_t*)arg) = getSn_TxMAX(sn);
break;
case CS_GET_MAXRXBUF:
*((uint16_t*)arg) = getSn_RxMAX(sn);
break;
case CS_CLR_INTERRUPT:
if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
setSn_IR(sn,*(uint8_t*)arg);
break;
case CS_GET_INTERRUPT:
*((uint8_t*)arg) = getSn_IR(sn);
break;
case CS_SET_INTMASK:
if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
setSn_IMR(sn,*(uint8_t*)arg);
break;
case CS_GET_INTMASK:
*((uint8_t*)arg) = getSn_IMR(sn);
default:
return SOCKERR_ARG;
}
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg)
{
// M20131220 : Remove warning
//uint8_t tmp;
CHECK_SOCKNUM();
switch(sotype)
{
case SO_TTL:
setSn_TTL(sn,*(uint8_t*)arg);
break;
case SO_TOS:
setSn_TOS(sn,*(uint8_t*)arg);
break;
case SO_MSS:
setSn_MSSR(sn,*(uint16_t*)arg);
break;
case SO_DESTIP:
setSn_DIPR(sn, (uint8_t*)arg);
break;
case SO_DESTPORT:
setSn_DPORT(sn, *(uint16_t*)arg);
break;
#if _WIZCHIP_ != 5100
case SO_KEEPALIVESEND:
CHECK_SOCKMODE(Sn_MR_TCP);
#if _WIZCHIP_ > 5200
if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
#endif
setSn_CR(sn,Sn_CR_SEND_KEEP);
while(getSn_CR(sn) != 0)
{
// M20131220
//if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
if (getSn_IR(sn) & Sn_IR_TIMEOUT)
{
setSn_IR(sn, Sn_IR_TIMEOUT);
return SOCKERR_TIMEOUT;
}
}
break;
#if _WIZCHIP_ > 5200
case SO_KEEPALIVEAUTO:
CHECK_SOCKMODE(Sn_MR_TCP);
setSn_KPALVTR(sn,*(uint8_t*)arg);
break;
#endif
#endif
default:
return SOCKERR_ARG;
}
return SOCK_OK;
}
int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg)
{
CHECK_SOCKNUM();
switch(sotype)
{
case SO_FLAG:
*(uint8_t*)arg = getSn_MR(sn) & 0xF0;
break;
case SO_TTL:
*(uint8_t*) arg = getSn_TTL(sn);
break;
case SO_TOS:
*(uint8_t*) arg = getSn_TOS(sn);
break;
case SO_MSS:
*(uint8_t*) arg = getSn_MSSR(sn);
case SO_DESTIP:
getSn_DIPR(sn, (uint8_t*)arg);
break;
case SO_DESTPORT:
*(uint16_t*) arg = getSn_DPORT(sn);
break;
#if _WIZCHIP_ > 5200
case SO_KEEPALIVEAUTO:
CHECK_SOCKMODE(Sn_MR_TCP);
*(uint16_t*) arg = getSn_KPALVTR(sn);
break;
#endif
case SO_SENDBUF:
*(uint16_t*) arg = getSn_TX_FSR(sn);
case SO_RECVBUF:
*(uint16_t*) arg = getSn_RX_RSR(sn);
case SO_STATUS:
*(uint8_t*) arg = getSn_SR(sn);
break;
case SO_REMAINSIZE:
if(getSn_MR(sn) == Sn_MR_TCP)
*(uint16_t*)arg = getSn_RX_RSR(sn);
else
*(uint16_t*)arg = sock_remained_size[sn];
break;
case SO_PACKINFO:
CHECK_SOCKMODE(Sn_MR_TCP);
*(uint8_t*)arg = sock_pack_info[sn];
break;
default:
return SOCKERR_SOCKOPT;
}
return SOCK_OK;
}

View File

@@ -0,0 +1,469 @@
//*****************************************************************************
//
//! \file socket.h
//! \brief SOCKET APIs Header file.
//! \details SOCKET APIs like as berkeley socket api.
//! \version 1.0.2
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.2. Refer to M20140501
//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED
//! 2. Add the comment as zero byte udp data reception in getsockopt().
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
/**
* @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs
* @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface.
* But there is a little bit of difference.
* @details
* <b> Comparison between WIZnet and Berkeley SOCKET APIs </b>
* <table>
* <tr> <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td> </tr>
* <tr> <td>socket()</td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>bind()</b></td> <td>X</td> <td>O</td> </tr>
* <tr> <td><b>listen()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>connect()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>accept()</b></td> <td>X</td> <td>O</td> </tr>
* <tr> <td><b>recv()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>send()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>recvfrom()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>sendto()</b></td> <td>O</td> <td>O</td> </tr>
* <tr> <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td> </tr>
* </table>
* There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but,
* not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number,
* and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n
* When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port.
* When the listen SOCKET accepts a connection request from a client, it keeps listening.
* After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n
* Following figure shows network flow diagram by Berkeley SOCKET API.
* @image html Berkeley_SOCKET.jpg "<Berkeley SOCKET API>"
* But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n
* Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client,
* it is changed in order to communicate with the client.
* And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n
* If there're many listen SOCKET with same listen port number and a client requests a connection,
* the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n
* Following figure shows network flow diagram by WIZnet SOCKET API.
* @image html WIZnet_SOCKET.jpg "<WIZnet SOCKET API>"
*/
#ifndef _WIZCHIP_SOCKET_H_
#define _WIZCHIP_SOCKET_H_
// use this macro for exported names to avoid name clashes
#define WIZCHIP_EXPORT(name) wizchip_ ## name
#include "wizchip_conf.h"
#define SOCKET uint8_t ///< SOCKET type define for legacy driver
#define SOCK_OK 1 ///< Result is OK about socket process.
#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode.
#define SOCK_FATAL -1000 ///< Result is fatal error about socket process.
#define SOCK_ERROR 0
#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number
#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option
#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized
#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed.
#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation.
#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag
#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation.
#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument.
#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero
#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address
#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred
#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size.
#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication.
#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error.
/*
* SOCKET FLAG
*/
#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In \ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet
#define SF_IGMP_VER2 (Sn_MR_MC) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2.
#define SF_TCP_NODELAY (Sn_MR_ND) ///< In \ref Sn_MR_TCP, Use to nodelayed ack.
#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In \ref Sn_MR_UDP, Enable multicast mode.
#if _WIZCHIP_ == 5500
#define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In \ref Sn_MR_UDP or \ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500
#define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In \ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500
#define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In \ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500
#define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500
#endif
#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket().
/*
* UDP & MACRAW Packet Infomation
*/
#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet.
#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received.
#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet.
/**
* @ingroup WIZnet_socket_APIs
* @brief Open a socket.
* @details Initializes the socket with 'sn' passed as parameter and open.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param protocol Protocol type to operate such as TCP, UDP and MACRAW.
* @param port Port number to be bined.
* @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n
* Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK.
* @sa Sn_MR
*
* @return @b Success : The socket number @b 'sn' passed as parameter\n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
* @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n
* @ref SOCKERR_SOCKFLAG - Invaild socket flag.
*/
int8_t WIZCHIP_EXPORT(socket)(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag);
/**
* @ingroup WIZnet_socket_APIs
* @brief Close a socket.
* @details It closes the socket with @b'sn' passed as parameter.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
*
* @return @b Success : @ref SOCK_OK \n
* @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number
*/
int8_t WIZCHIP_EXPORT(close)(uint8_t sn);
/**
* @ingroup WIZnet_socket_APIs
* @brief Listen to a connection request from a client.
* @details It is listening to a connection request from a client.
* If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @return @b Success : @ref SOCK_OK \n
* @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n
* @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly.
*/
int8_t WIZCHIP_EXPORT(listen)(uint8_t sn);
/**
* @ingroup WIZnet_socket_APIs
* @brief Try to connect a server.
* @details It requests connection to the server with destination IP address and port number passed as parameter.\n
* @note It is valid only in TCP client mode.
* In block io mode, it does not return until connection is completed.
* In Non-block io mode, it return @ref SOCK_BUSY immediately.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
* @param port Destination port number.
*
* @return @b Success : @ref SOCK_OK \n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
* @ref SOCKERR_SOCKMODE - Invalid socket mode\n
* @ref SOCKERR_SOCKINIT - Socket is not initialized\n
* @ref SOCKERR_IPINVALID - Wrong server IP address\n
* @ref SOCKERR_PORTZERO - Server port zero\n
* @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n
* @ref SOCK_BUSY - In non-block io mode, it returned immediately\n
*/
int8_t WIZCHIP_EXPORT(connect)(uint8_t sn, uint8_t * addr, uint16_t port);
/**
* @ingroup WIZnet_socket_APIs
* @brief Try to disconnect a connection socket.
* @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client.
* @note It is valid only in TCP server or client mode. \n
* In block io mode, it does not return until disconnection is completed. \n
* In Non-block io mode, it return @ref SOCK_BUSY immediately. \n
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @return @b Success : @ref SOCK_OK \n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_TIMEOUT - Timeout occurred \n
* @ref SOCK_BUSY - Socket is busy.
*/
int8_t WIZCHIP_EXPORT(disconnect)(uint8_t sn);
/**
* @ingroup WIZnet_socket_APIs
* @brief Send data to the connected peer in TCP socket.
* @details It is used to send outgoing data to the connected socket.
* @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n
* In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n
* In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer containing data to be sent.
* @param len The byte length of data in buf.
* @return @b Success : The sent data size \n
* @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
* @ref SOCKERR_TIMEOUT - Timeout occurred \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCK_BUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(send)(uint8_t sn, uint8_t * buf, uint16_t len);
/**
* @ingroup WIZnet_socket_APIs
* @brief Receive data from the connected peer.
* @details It is used to read incoming data from the connected socket.\n
* It waits for data as much as the application wants to receive.
* @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n
* In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer. \n
* In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer. \n
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer to read incoming data.
* @param len The max data length of data in buf.
* @return @b Success : The real received data size \n
* @b Fail :\n
* @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCK_BUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len);
/**
* @ingroup WIZnet_socket_APIs
* @brief Sends datagram to the peer with destination IP address and port number passed as parameter.
* @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n
* Even if the connectionless socket has been previously connected to a specific address,
* the address and port number parameters override the destination address for that particular datagram only.
* @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than <I>len</I>.
* In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer to send outgoing data.
* @param len The byte length of data in buf.
* @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
* @param port Destination port number.
*
* @return @b Success : The sent data size \n
* @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
* @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCKERR_IPINVALID - Wrong server IP address\n
* @ref SOCKERR_PORTZERO - Server port zero\n
* @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n
* @ref SOCKERR_TIMEOUT - Timeout occurred \n
* @ref SOCK_BUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(sendto)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);
/**
* @ingroup WIZnet_socket_APIs
* @brief Receive datagram of UDP or MACRAW
* @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n
* This function is used to receive UDP and MAC_RAW mode, and handle the header as well.
* This function can divide to received the packet data.
* On the MACRAW SOCKET, the addr and port parameters are ignored.
* @note In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer
* In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @param buf Pointer buffer to read incoming data.
* @param len The max data length of data in buf.
* When the received packet size <= len, receives data as packet sized.
* When others, receives data as len.
* @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
* It is valid only when the first call recvfrom for receiving the packet.
* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
* @param port Pointer variable of destination port number.
* It is valid only when the first call recvform for receiving the packet.
* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
*
* @return @b Success : This function return real received data size for success.\n
* @b Fail : @ref SOCKERR_DATALEN - zero data length \n
* @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
* @ref SOCKERR_SOCKNUM - Invalid socket number \n
* @ref SOCKBUSY - Socket is busy.
*/
int32_t WIZCHIP_EXPORT(recvfrom)(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
/////////////////////////////
// SOCKET CONTROL & OPTION //
/////////////////////////////
#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt().
#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt().
/**
* @defgroup DATA_TYPE DATA TYPE
*/
/**
* @ingroup DATA_TYPE
* @brief The kind of Socket Interrupt.
* @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR()
*/
typedef enum
{
SIK_CONNECTED = (1 << 0), ///< connected
SIK_DISCONNECTED = (1 << 1), ///< disconnected
SIK_RECEIVED = (1 << 2), ///< data received
SIK_TIMEOUT = (1 << 3), ///< timeout occurred
SIK_SENT = (1 << 4), ///< send ok
SIK_ALL = 0x1F, ///< all interrupt
}sockint_kind;
/**
* @ingroup DATA_TYPE
* @brief The type of @ref ctlsocket().
*/
typedef enum
{
CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK
CS_GET_IOMODE, ///< get socket IO mode
CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory
CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory
CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind
CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind
CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind
CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind
}ctlsock_type;
/**
* @ingroup DATA_TYPE
* @brief The type of socket option in @ref setsockopt() or @ref getsockopt()
*/
typedef enum
{
SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket().
SO_TTL, ///< Set/Get TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() )
SO_TOS, ///< Set/Get TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() )
SO_MSS, ///< Set/Get MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() )
SO_DESTIP, ///< Set/Get the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() )
SO_DESTPORT, ///< Set/Get the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() )
#if _WIZCHIP_ != 5100
SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode
#if _WIZCHIP_ > 5200
SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode
#endif
#endif
SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR()
SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR()
SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR()
SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode.
SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode.
}sockopt_type;
/**
* @ingroup WIZnet_socket_APIs
* @brief Control socket.
* @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information.
* Refer to @ref ctlsock_type.
* @param sn socket number
* @param cstype type of control socket. refer to @ref ctlsock_type.
* @param arg Data type and value is determined according to @ref ctlsock_type. \n
* <table>
* <tr> <td> @b cstype </td> <td> @b data type</td><td>@b value</td></tr>
* <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td> uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr>
* <tr> <td> @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0 ~ 16K </td></tr>
* <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind </td><td> @ref SIK_CONNECTED, etc. </td></tr>
* </table>
* @return @b Success @ref SOCK_OK \n
* @b fail @ref SOCKERR_ARG - Invalid argument\n
*/
int8_t WIZCHIP_EXPORT(ctlsocket)(uint8_t sn, ctlsock_type cstype, void* arg);
/**
* @ingroup WIZnet_socket_APIs
* @brief set socket options
* @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type.
*
* @param sn socket number
* @param sotype socket option type. refer to @ref sockopt_type
* @param arg Data type and value is determined according to <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td> @b data type</td><td>@b value</td></tr>
* <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
* <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
* <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
* <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
* <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
* <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td> null </td></tr>
* <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>
* </table>
* @return
* - @b Success : @ref SOCK_OK \n
* - @b Fail
* - @ref SOCKERR_SOCKNUM - Invalid Socket number \n
* - @ref SOCKERR_SOCKMODE - Invalid socket mode \n
* - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n
* - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n
*/
int8_t WIZCHIP_EXPORT(setsockopt)(uint8_t sn, sockopt_type sotype, void* arg);
/**
* @ingroup WIZnet_socket_APIs
* @brief get socket options
* @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type
* @param sn socket number
* @param sotype socket option type. refer to @ref sockopt_type
* @param arg Data type and value is determined according to <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td>@b data type</td><td>@b value</td></tr>
* <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref SF_ETHER_OWN, etc... </td> </tr>
* <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
* <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
* <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
* <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> </td></tr>
* <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>
* <tr> <td> @ref SO_SENDBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
* <tr> <td> @ref SO_RECVBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
* <tr> <td> @ref SO_STATUS </td> <td> uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr>
* <tr> <td> @ref SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr>
* <tr> <td> @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc... </td></tr>
* </table>
* @return
* - @b Success : @ref SOCK_OK \n
* - @b Fail
* - @ref SOCKERR_SOCKNUM - Invalid Socket number \n
* - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n
* - @ref SOCKERR_SOCKMODE - Invalid socket mode \n
* @note
* The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n
* When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero,
* This means the zero byte UDP data(UDP Header only) received.
*/
int8_t WIZCHIP_EXPORT(getsockopt)(uint8_t sn, sockopt_type sotype, void* arg);
#endif // _WIZCHIP_SOCKET_H_

View File

@@ -0,0 +1,206 @@
// dpgeorge: this file taken from w5500/w5500.c and adapted to W5200
//*****************************************************************************
//
//! \file w5500.c
//! \brief W5500 HAL Interface.
//! \version 1.0.1
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.2
//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
//! Fixed the problem on porting into under 32bit MCU
//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
//! Thank for your interesting and serious advices.
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.0.1
//! 1. Remove warning
//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
//! for loop optimized(removed). refer to M20131220
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include "w5200.h"
#define SMASK (0x7ff) /* tx buffer mask */
#define RMASK (0x7ff) /* rx buffer mask */
#define SSIZE (2048) /* max tx buffer size */
#define RSIZE (2048) /* max rx buffer size */
#define TXBUF_BASE (0x8000)
#define RXBUF_BASE (0xc000)
#define SBASE(sn) (TXBUF_BASE + SSIZE * (sn)) /* tx buffer base for socket sn */
#define RBASE(sn) (RXBUF_BASE + RSIZE * (sn)) /* rx buffer base for socket sn */
uint8_t WIZCHIP_READ(uint32_t AddrSel) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[4] = {
AddrSel >> 8,
AddrSel,
0x00,
0x01,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
uint8_t ret;
WIZCHIP.IF.SPI._read_bytes(&ret, 1);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
return ret;
}
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[5] = {
AddrSel >> 8,
AddrSel,
0x80,
0x01,
wb,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 5);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[4] = {
AddrSel >> 8,
AddrSel,
0x00 | ((len >> 8) & 0x7f),
len & 0xff,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
WIZCHIP.IF.SPI._read_bytes(pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) {
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
uint8_t spi_data[4] = {
AddrSel >> 8,
AddrSel,
0x80 | ((len >> 8) & 0x7f),
len & 0xff,
};
WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
WIZCHIP.IF.SPI._write_bytes(pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
uint16_t getSn_TX_FSR(uint8_t sn) {
uint16_t val = 0, val1 = 0;
do {
val1 = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1);
if (val1 != 0) {
val = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1);
}
} while (val != val1);
return val;
}
uint16_t getSn_RX_RSR(uint8_t sn) {
uint16_t val = 0, val1 = 0;
do {
val1 = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1);
if (val1 != 0) {
val = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1);
}
} while (val != val1);
return val;
}
void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) {
if (len == 0) {
return;
}
uint16_t ptr = getSn_TX_WR(sn);
uint16_t offset = ptr & SMASK;
uint32_t addr = offset + SBASE(sn);
if (offset + len > SSIZE) {
// implement wrap-around circular buffer
uint16_t size = SSIZE - offset;
WIZCHIP_WRITE_BUF(addr, wizdata, size);
WIZCHIP_WRITE_BUF(SBASE(sn), wizdata + size, len - size);
} else {
WIZCHIP_WRITE_BUF(addr, wizdata, len);
}
ptr += len;
setSn_TX_WR(sn, ptr);
}
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) {
if (len == 0) {
return;
}
uint16_t ptr = getSn_RX_RD(sn);
uint16_t offset = ptr & RMASK;
uint16_t addr = RBASE(sn) + offset;
if (offset + len > RSIZE) {
// implement wrap-around circular buffer
uint16_t size = RSIZE - offset;
WIZCHIP_READ_BUF(addr, wizdata, size);
WIZCHIP_READ_BUF(RBASE(sn), wizdata + size, len - size);
} else {
WIZCHIP_READ_BUF(addr, wizdata, len);
}
ptr += len;
setSn_RX_RD(sn, ptr);
}
void wiz_recv_ignore(uint8_t sn, uint16_t len) {
uint16_t ptr = getSn_RX_RD(sn);
ptr += len;
setSn_RX_RD(sn, ptr);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,237 @@
//*****************************************************************************
//
//! \file w5500.c
//! \brief W5500 HAL Interface.
//! \version 1.0.1
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.2
//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
//! Fixed the problem on porting into under 32bit MCU
//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
//! Thank for your interesting and serious advices.
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.0.1
//! 1. Remove warning
//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
//! for loop optimized(removed). refer to M20131220
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
//#include <stdio.h>
#include "w5500.h"
#define _W5500_SPI_VDM_OP_ 0x00
#define _W5500_SPI_FDM_OP_LEN1_ 0x01
#define _W5500_SPI_FDM_OP_LEN2_ 0x02
#define _W5500_SPI_FDM_OP_LEN4_ 0x03
////////////////////////////////////////////////////
uint8_t WIZCHIP_READ(uint32_t AddrSel)
{
uint8_t ret;
uint8_t spi_data[3];
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//ret = WIZCHIP.IF.SPI._read_byte();
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3);
Chip_SSP_ReadFrames_Blocking(LPC_SSP0, &ret, 1);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
return ret;
}
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
{
uint8_t spi_data[4];
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//WIZCHIP.IF.SPI._write_byte(wb);
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
spi_data[3] = wb;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 4);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint8_t spi_data[3];
//uint16_t i;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//for(i = 0; i < len; i++)
// pBuf[i] = WIZCHIP.IF.SPI._read_byte();
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3);
Chip_SSP_ReadFrames_Blocking(LPC_SSP0, pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint8_t spi_data[3];
//uint16_t i;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
//for(i = 0; i < len; i++)
// WIZCHIP.IF.SPI._write_byte(pBuf[i]);
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, spi_data, 3);
Chip_SSP_WriteFrames_Blocking(LPC_SSP0, pBuf, len);
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
uint16_t getSn_TX_FSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_TX_FSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
}
}while (val != val1);
return val;
}
uint16_t getSn_RX_RSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_RX_RSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
}
}while (val != val1);
return val;
}
void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr = 0;
uint32_t addrsel = 0;
if(len == 0) return;
ptr = getSn_TX_WR(sn);
//M20140501 : implict type casting -> explict type casting
//addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
//
WIZCHIP_WRITE_BUF(addrsel,wizdata, len);
ptr += len;
setSn_TX_WR(sn,ptr);
}
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr = 0;
uint32_t addrsel = 0;
if(len == 0) return;
ptr = getSn_RX_RD(sn);
//M20140501 : implict type casting -> explict type casting
//addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
//
WIZCHIP_READ_BUF(addrsel, wizdata, len);
ptr += len;
setSn_RX_RD(sn,ptr);
}
void wiz_recv_ignore(uint8_t sn, uint16_t len)
{
uint16_t ptr = 0;
ptr = getSn_RX_RD(sn);
ptr += len;
setSn_RX_RD(sn,ptr);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,657 @@
//****************************************************************************/
//!
//! \file wizchip_conf.c
//! \brief WIZCHIP Config Header File.
//! \version 1.0.1
//! \date 2013/10/21
//! \par Revision history
//! <2014/05/01> V1.0.1 Refer to M20140501
//! 1. Explicit type casting in wizchip_bus_readbyte() & wizchip_bus_writebyte()
// Issued by Mathias ClauBen.
//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
//! For remove the warning when pointer type size is not 32bit.
//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type.
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************/
//A20140501 : for use the type - ptrdiff_t
#include <stddef.h>
//
#include "wizchip_conf.h"
/**
* @brief Default function to enable interrupt.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cris_enter(void) {};
/**
* @brief Default function to disable interrupt.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cris_exit(void) {};
/**
* @brief Default function to select chip.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cs_select(void) {};
/**
* @brief Default function to deselect chip.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_cs_deselect(void) {};
/**
* @brief Default function to read in direct or indirect interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
//M20140501 : Explict pointer type casting
//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *) AddrSel); };
uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); };
/**
* @brief Default function to write in direct or indirect interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
//M20140501 : Explict pointer type casting
//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*) AddrSel) = wb; };
void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; };
/**
* @brief Default function to read in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_spi_readbytes(uint8_t *buf, uint32_t len) {}
/**
* @brief Default function to write in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called.
*/
void wizchip_spi_writebytes(const uint8_t *buf, uint32_t len) {}
/**
* @\ref _WIZCHIP instance
*/
_WIZCHIP WIZCHIP =
{
.id = _WIZCHIP_ID_,
.if_mode = _WIZCHIP_IO_MODE_,
.CRIS._enter = wizchip_cris_enter,
.CRIS._exit = wizchip_cris_exit,
.CS._select = wizchip_cs_select,
.CS._deselect = wizchip_cs_deselect,
.IF.BUS._read_byte = wizchip_bus_readbyte,
.IF.BUS._write_byte = wizchip_bus_writebyte
// .IF.SPI._read_byte = wizchip_spi_readbyte,
// .IF.SPI._write_byte = wizchip_spi_writebyte
};
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
static uint8_t _SUBN_[4]; // subnet
#endif
static uint8_t _DNS_[4]; // DNS server ip address
static dhcp_mode _DHCP_; // DHCP mode
void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void))
{
if(!cris_en || !cris_ex)
{
WIZCHIP.CRIS._enter = wizchip_cris_enter;
WIZCHIP.CRIS._exit = wizchip_cris_exit;
}
else
{
WIZCHIP.CRIS._enter = cris_en;
WIZCHIP.CRIS._exit = cris_ex;
}
}
void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void))
{
if(!cs_sel || !cs_desel)
{
WIZCHIP.CS._select = wizchip_cs_select;
WIZCHIP.CS._deselect = wizchip_cs_deselect;
}
else
{
WIZCHIP.CS._select = cs_sel;
WIZCHIP.CS._deselect = cs_desel;
}
}
void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb))
{
while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_));
if(!bus_rb || !bus_wb)
{
WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte;
WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte;
}
else
{
WIZCHIP.IF.BUS._read_byte = bus_rb;
WIZCHIP.IF.BUS._write_byte = bus_wb;
}
}
void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t))
{
while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
if(!spi_rb || !spi_wb)
{
WIZCHIP.IF.SPI._read_bytes = wizchip_spi_readbytes;
WIZCHIP.IF.SPI._write_bytes = wizchip_spi_writebytes;
}
else
{
WIZCHIP.IF.SPI._read_bytes = spi_rb;
WIZCHIP.IF.SPI._write_bytes = spi_wb;
}
}
int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
{
uint8_t tmp = 0;
uint8_t* ptmp[2] = {0,0};
switch(cwtype)
{
case CW_RESET_WIZCHIP:
wizchip_sw_reset();
break;
case CW_INIT_WIZCHIP:
if(arg != 0)
{
ptmp[0] = (uint8_t*)arg;
ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_;
}
return wizchip_init(ptmp[0], ptmp[1]);
case CW_CLR_INTERRUPT:
wizchip_clrinterrupt(*((intr_kind*)arg));
break;
case CW_GET_INTERRUPT:
*((intr_kind*)arg) = wizchip_getinterrupt();
break;
case CW_SET_INTRMASK:
wizchip_setinterruptmask(*((intr_kind*)arg));
break;
case CW_GET_INTRMASK:
*((intr_kind*)arg) = wizchip_getinterruptmask();
break;
#if _WIZCHIP_ > 5100
case CW_SET_INTRTIME:
setINTLEVEL(*(uint16_t*)arg);
break;
case CW_GET_INTRTIME:
*(uint16_t*)arg = getINTLEVEL();
break;
#endif
case CW_GET_ID:
((uint8_t*)arg)[0] = WIZCHIP.id[0];
((uint8_t*)arg)[1] = WIZCHIP.id[1];
((uint8_t*)arg)[2] = WIZCHIP.id[2];
((uint8_t*)arg)[3] = WIZCHIP.id[3];
((uint8_t*)arg)[4] = WIZCHIP.id[4];
((uint8_t*)arg)[5] = 0;
break;
#if _WIZCHIP_ == 5500
case CW_RESET_PHY:
wizphy_reset();
break;
case CW_SET_PHYCONF:
wizphy_setphyconf((wiz_PhyConf*)arg);
break;
case CW_GET_PHYCONF:
wizphy_getphyconf((wiz_PhyConf*)arg);
break;
case CW_GET_PHYSTATUS:
break;
case CW_SET_PHYPOWMODE:
return wizphy_setphypmode(*(uint8_t*)arg);
#endif
case CW_GET_PHYPOWMODE:
tmp = wizphy_getphypmode();
if((int8_t)tmp == -1) return -1;
*(uint8_t*)arg = tmp;
break;
case CW_GET_PHYLINK:
tmp = wizphy_getphylink();
if((int8_t)tmp == -1) return -1;
*(uint8_t*)arg = tmp;
break;
default:
return -1;
}
return 0;
}
int8_t ctlnetwork(ctlnetwork_type cntype, void* arg)
{
switch(cntype)
{
case CN_SET_NETINFO:
wizchip_setnetinfo((wiz_NetInfo*)arg);
break;
case CN_GET_NETINFO:
wizchip_getnetinfo((wiz_NetInfo*)arg);
break;
case CN_SET_NETMODE:
return wizchip_setnetmode(*(netmode_type*)arg);
case CN_GET_NETMODE:
*(netmode_type*)arg = wizchip_getnetmode();
break;
case CN_SET_TIMEOUT:
wizchip_settimeout((wiz_NetTimeout*)arg);
break;
case CN_GET_TIMEOUT:
wizchip_gettimeout((wiz_NetTimeout*)arg);
break;
default:
return -1;
}
return 0;
}
void wizchip_sw_reset(void)
{
uint8_t gw[4], sn[4], sip[4];
uint8_t mac[6];
getSHAR(mac);
getGAR(gw); getSUBR(sn); getSIPR(sip);
setMR(MR_RST);
getMR(); // for delay
setSHAR(mac);
setGAR(gw);
setSUBR(sn);
setSIPR(sip);
}
int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize)
{
int8_t i;
int8_t tmp = 0;
wizchip_sw_reset();
if(txsize)
{
tmp = 0;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
tmp += txsize[i];
if(tmp > 16) return -1;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
setSn_TXBUF_SIZE(i, txsize[i]);
}
if(rxsize)
{
tmp = 0;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
tmp += rxsize[i];
if(tmp > 16) return -1;
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
setSn_RXBUF_SIZE(i, rxsize[i]);
}
return 0;
}
void wizchip_clrinterrupt(intr_kind intr)
{
uint8_t ir = (uint8_t)intr;
uint8_t sir = (uint8_t)((uint16_t)intr >> 8);
#if _WIZCHIP_ < 5500
ir |= (1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
ir |= (1 << 6);
#endif
#if _WIZCHIP_ < 5200
sir &= 0x0F;
#endif
#if _WIZCHIP_ == 5100
ir |= sir;
setIR(ir);
#else
setIR(ir);
setSIR(sir);
#endif
}
intr_kind wizchip_getinterrupt(void)
{
uint8_t ir = 0;
uint8_t sir = 0;
uint16_t ret = 0;
#if _WIZCHIP_ == 5100
ir = getIR();
sir = ir 0x0F;
#else
ir = getIR();
sir = getSIR();
#endif
#if _WIZCHIP_ < 5500
ir &= ~(1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
ir &= ~(1 << 6);
#endif
ret = sir;
ret = (ret << 8) + ir;
return (intr_kind)ret;
}
void wizchip_setinterruptmask(intr_kind intr)
{
uint8_t imr = (uint8_t)intr;
uint8_t simr = (uint8_t)((uint16_t)intr >> 8);
#if _WIZCHIP_ < 5500
imr &= ~(1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
imr &= ~(1 << 6);
#endif
#if _WIZCHIP_ < 5200
simr &= 0x0F;
#endif
#if _WIZCHIP_ == 5100
imr |= simr;
setIMR(imr);
#else
setIMR(imr);
setSIMR(simr);
#endif
}
intr_kind wizchip_getinterruptmask(void)
{
uint8_t imr = 0;
uint8_t simr = 0;
uint16_t ret = 0;
#if _WIZCHIP_ == 5100
imr = getIMR();
simr = imr 0x0F;
#else
imr = getIMR();
simr = getSIMR();
#endif
#if _WIZCHIP_ < 5500
imr &= ~(1<<4); // IK_WOL
#endif
#if _WIZCHIP_ == 5200
imr &= ~(1 << 6); // IK_DEST_UNREACH
#endif
ret = simr;
ret = (ret << 8) + imr;
return (intr_kind)ret;
}
int8_t wizphy_getphylink(void)
{
int8_t tmp;
#if _WIZCHIP_ == 5200
if(getPHYSTATUS() & PHYSTATUS_LINK)
tmp = PHY_LINK_ON;
else
tmp = PHY_LINK_OFF;
#elif _WIZCHIP_ == 5500
if(getPHYCFGR() & PHYCFGR_LNK_ON)
tmp = PHY_LINK_ON;
else
tmp = PHY_LINK_OFF;
#else
tmp = -1;
#endif
return tmp;
}
#if _WIZCHIP_ > 5100
int8_t wizphy_getphypmode(void)
{
int8_t tmp = 0;
#if _WIZCHIP_ == 5200
if(getPHYSTATUS() & PHYSTATUS_POWERDOWN)
tmp = PHY_POWER_DOWN;
else
tmp = PHY_POWER_NORM;
#elif _WIZCHIP_ == 5500
if(getPHYCFGR() & PHYCFGR_OPMDC_PDOWN)
tmp = PHY_POWER_DOWN;
else
tmp = PHY_POWER_NORM;
#else
tmp = -1;
#endif
return tmp;
}
#endif
#if _WIZCHIP_ == 5500
void wizphy_reset(void)
{
uint8_t tmp = getPHYCFGR();
tmp &= PHYCFGR_RST;
setPHYCFGR(tmp);
tmp = getPHYCFGR();
tmp |= ~PHYCFGR_RST;
setPHYCFGR(tmp);
}
void wizphy_setphyconf(wiz_PhyConf* phyconf)
{
uint8_t tmp = 0;
if(phyconf->by == PHY_CONFBY_SW)
tmp |= PHYCFGR_OPMD;
else
tmp &= ~PHYCFGR_OPMD;
if(phyconf->mode == PHY_MODE_AUTONEGO)
tmp |= PHYCFGR_OPMDC_ALLA;
else
{
if(phyconf->duplex == PHY_DUPLEX_FULL)
{
if(phyconf->speed == PHY_SPEED_100)
tmp |= PHYCFGR_OPMDC_100F;
else
tmp |= PHYCFGR_OPMDC_10F;
}
else
{
if(phyconf->speed == PHY_SPEED_100)
tmp |= PHYCFGR_OPMDC_100H;
else
tmp |= PHYCFGR_OPMDC_10H;
}
}
setPHYCFGR(tmp);
wizphy_reset();
}
void wizphy_getphyconf(wiz_PhyConf* phyconf)
{
uint8_t tmp = 0;
tmp = getPHYCFGR();
phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW;
switch(tmp & PHYCFGR_OPMDC_ALLA)
{
case PHYCFGR_OPMDC_ALLA:
case PHYCFGR_OPMDC_100FA:
phyconf->mode = PHY_MODE_AUTONEGO;
break;
default:
phyconf->mode = PHY_MODE_MANUAL;
break;
}
switch(tmp & PHYCFGR_OPMDC_ALLA)
{
case PHYCFGR_OPMDC_100FA:
case PHYCFGR_OPMDC_100F:
case PHYCFGR_OPMDC_100H:
phyconf->speed = PHY_SPEED_100;
break;
default:
phyconf->speed = PHY_SPEED_10;
break;
}
switch(tmp & PHYCFGR_OPMDC_ALLA)
{
case PHYCFGR_OPMDC_100FA:
case PHYCFGR_OPMDC_100F:
case PHYCFGR_OPMDC_10F:
phyconf->duplex = PHY_DUPLEX_FULL;
break;
default:
phyconf->duplex = PHY_DUPLEX_HALF;
break;
}
}
void wizphy_getphystat(wiz_PhyConf* phyconf)
{
uint8_t tmp = getPHYCFGR();
phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF;
phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10;
}
int8_t wizphy_setphypmode(uint8_t pmode)
{
uint8_t tmp = 0;
tmp = getPHYCFGR();
if((tmp & PHYCFGR_OPMD)== 0) return -1;
tmp &= ~PHYCFGR_OPMDC_ALLA;
if( pmode == PHY_POWER_DOWN)
tmp |= PHYCFGR_OPMDC_PDOWN;
else
tmp |= PHYCFGR_OPMDC_ALLA;
setPHYCFGR(tmp);
wizphy_reset();
tmp = getPHYCFGR();
if( pmode == PHY_POWER_DOWN)
{
if(tmp & PHYCFGR_OPMDC_PDOWN) return 0;
}
else
{
if(tmp & PHYCFGR_OPMDC_ALLA) return 0;
}
return -1;
}
#endif
void wizchip_setnetinfo(wiz_NetInfo* pnetinfo)
{
setSHAR(pnetinfo->mac);
setGAR(pnetinfo->gw);
setSUBR(pnetinfo->sn);
setSIPR(pnetinfo->ip);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
_SUBN_[0] = pnetinfo->sn[0];
_SUBN_[1] = pnetinfo->sn[1];
_SUBN_[2] = pnetinfo->sn[2];
_SUBN_[3] = pnetinfo->sn[3];
#endif
_DNS_[0] = pnetinfo->dns[0];
_DNS_[1] = pnetinfo->dns[1];
_DNS_[2] = pnetinfo->dns[2];
_DNS_[3] = pnetinfo->dns[3];
_DHCP_ = pnetinfo->dhcp;
}
void wizchip_getnetinfo(wiz_NetInfo* pnetinfo)
{
getSHAR(pnetinfo->mac);
getGAR(pnetinfo->gw);
getSUBR(pnetinfo->sn);
getSIPR(pnetinfo->ip);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
pnetinfo->sn[0] = _SUBN_[0];
pnetinfo->sn[1] = _SUBN_[1];
pnetinfo->sn[2] = _SUBN_[2];
pnetinfo->sn[3] = _SUBN_[3];
#endif
pnetinfo->dns[0]= _DNS_[0];
pnetinfo->dns[1]= _DNS_[1];
pnetinfo->dns[2]= _DNS_[2];
pnetinfo->dns[3]= _DNS_[3];
pnetinfo->dhcp = _DHCP_;
}
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
uint8_t *wizchip_getsubn(void) {
return _SUBN_;
}
#endif
int8_t wizchip_setnetmode(netmode_type netmode)
{
uint8_t tmp = 0;
#if _WIZCHIP_ != 5500
if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1;
#else
if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1;
#endif
tmp = getMR();
tmp |= (uint8_t)netmode;
setMR(tmp);
return 0;
}
netmode_type wizchip_getnetmode(void)
{
return (netmode_type) getMR();
}
void wizchip_settimeout(wiz_NetTimeout* nettime)
{
setRCR(nettime->retry_cnt);
setRTR(nettime->time_100us);
}
void wizchip_gettimeout(wiz_NetTimeout* nettime)
{
nettime->retry_cnt = getRCR();
nettime->time_100us = getRTR();
}

View File

@@ -0,0 +1,552 @@
//*****************************************************************************
//
//! \file wizchip_conf.h
//! \brief WIZCHIP Config Header File.
//! \version 1.0.0
//! \date 2013/10/21
//! \par Revision history
//! <2013/10/21> 1st Release
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
/**
* @defgroup extra_functions 2. WIZnet Extra Functions
*
* @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions.
* @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n
*
*/
#ifndef _WIZCHIP_CONF_H_
#define _WIZCHIP_CONF_H_
#include <stdint.h>
/**
* @brief Select WIZCHIP.
* @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n
* ex> <code> #define \_WIZCHIP_ 5500 </code>
*/
#define _WIZCHIP_ 5200 // 5100, 5200, 5500
#define _WIZCHIP_IO_MODE_NONE_ 0x0000
#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */
#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */
//#define _WIZCHIP_IO_MODE_IIC_ 0x0400
//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800
// Add to
//
#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */
#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */
#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/
#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/
#if (_WIZCHIP_ == 5100)
#define _WIZCHIP_ID_ "W5100\0"
/**
* @brief Define interface mode.
* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
*/
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
#elif (_WIZCHIP_ == 5200)
#define _WIZCHIP_ID_ "W5200\0"
/**
* @brief Define interface mode.
* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
*/
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
#include "w5200/w5200.h"
#elif (_WIZCHIP_ == 5500)
#define _WIZCHIP_ID_ "W5500\0"
/**
* @brief Define interface mode. \n
* @todo Should select interface mode as chip.
* - @ref \_WIZCHIP_IO_MODE_SPI_ \n
* -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n
* -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n
* - @ref \_WIZCHIP_IO_MODE_BUS_ \n
* - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n
* - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n
* - Others will be defined in future. \n\n
* ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code>
*
*/
//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_
#include "w5500/w5500.h"
#else
#error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!"
#endif
#ifndef _WIZCHIP_IO_MODE_
#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!"
#endif
/**
* @brief Define I/O base address when BUS IF mode.
* @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_,
* @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n
* ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code>
*/
#define _WIZCHIP_IO_BASE_ 0x00000000 //
#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS
#ifndef _WIZCHIP_IO_BASE_
#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map."
#endif
#endif
#if _WIZCHIP_ > 5100
#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP
#else
#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP
#endif
/********************************************************
* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC.
*********************************************************/
/**
* @ingroup DATA_TYPE
* @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200
*/
typedef struct __WIZCHIP
{
uint16_t if_mode; ///< host interface mode
uint8_t id[6]; ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on.
/**
* The set of critical section callback func.
*/
struct _CRIS
{
void (*_enter) (void); ///< crtical section enter
void (*_exit) (void); ///< critial section exit
}CRIS;
/**
* The set of @ref\_WIZCHIP_ select control callback func.
*/
struct _CS
{
void (*_select) (void); ///< @ref \_WIZCHIP_ selected
void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected
}CS;
/**
* The set of interface IO callback func.
*/
union _IF
{
/**
* For BUS interface IO
*/
struct
{
uint8_t (*_read_byte) (uint32_t AddrSel);
void (*_write_byte) (uint32_t AddrSel, uint8_t wb);
}BUS;
/**
* For SPI interface IO
*/
struct
{
void (*_read_bytes) (uint8_t *buf, uint32_t len);
void (*_write_bytes) (const uint8_t *buf, uint32_t len);
}SPI;
// To be added
//
}IF;
}_WIZCHIP;
extern _WIZCHIP WIZCHIP;
/**
* @ingroup DATA_TYPE
* WIZCHIP control type enumration used in @ref ctlwizchip().
*/
typedef enum
{
CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly
CW_INIT_WIZCHIP, ///< Inializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t.
CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP
CW_CLR_INTERRUPT, ///< Clears interrupt
CW_SET_INTRMASK, ///< Masks interrupt
CW_GET_INTRMASK, ///< Get interrupt mask
CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt.
CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt.
CW_GET_ID, ///< Gets WIZCHIP name.
#if _WIZCHIP_ == 5500
CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5000
CW_SET_PHYCONF, ///< When PHY configured by interal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000
CW_GET_PHYCONF, ///< Get PHY operation mode in interal register. Valid Only W5000
CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5000
CW_SET_PHYPOWMODE, ///< Set PHY power mode as noraml and down when PHYSTATUS.OPMD == 1. Valid Only W5000
#endif
CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal
CW_GET_PHYLINK ///< Get PHY Link status
}ctlwizchip_type;
/**
* @ingroup DATA_TYPE
* Network control type enumration used in @ref ctlnetwork().
*/
typedef enum
{
CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo
CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo
CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode
CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode
CN_SET_TIMEOUT, ///< Set network timeout as retry count and time.
CN_GET_TIMEOUT, ///< Get network timeout as retry count and time.
}ctlnetwork_type;
/**
* @ingroup DATA_TYPE
* Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK
* and CW_GET_INTRMASK is used in @ref ctlnetwork().
* It can be used with OR operation.
*/
typedef enum
{
#if _WIZCHIP_ > 5200
IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500.
#endif
IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected
#if _WIZCHIP_ != 5200
IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreable, No use in W5200
#endif
IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred
IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt
IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt
IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt
IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt
#if _WIZCHIP_ > 5100
IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100
IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100
IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100
IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100
#endif
#if _WIZCHIP_ > 5100
IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrpt
#else
IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrpt
#endif
}intr_kind;
#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin
#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register
#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting.
#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation
#define PHY_SPEED_10 0 ///< Link Speed 10
#define PHY_SPEED_100 1 ///< Link Speed 100
#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex
#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex
#define PHY_LINK_OFF 0 ///< Link Off
#define PHY_LINK_ON 1 ///< Link On
#define PHY_POWER_NORM 0 ///< PHY power normal mode
#define PHY_POWER_DOWN 1 ///< PHY power down mode
#if _WIZCHIP_ == 5500
/**
* @ingroup DATA_TYPE
* It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500,
* and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n
* Valid only in W5500.
*/
typedef struct wiz_PhyConf_t
{
uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW
uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO
uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100
uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL
//uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN
//uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF
}wiz_PhyConf;
#endif
/**
* @ingroup DATA_TYPE
* It used in setting dhcp_mode of @ref wiz_NetInfo.
*/
typedef enum
{
NETINFO_STATIC = 1, ///< Static IP configuration by manually.
NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever
}dhcp_mode;
/**
* @ingroup DATA_TYPE
* Network Information for WIZCHIP
*/
typedef struct wiz_NetInfo_t
{
uint8_t mac[6]; ///< Source Mac Address
uint8_t ip[4]; ///< Source IP Address
uint8_t sn[4]; ///< Subnet Mask
uint8_t gw[4]; ///< Gateway IP Address
uint8_t dns[4]; ///< DNS server IP Address
dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP
}wiz_NetInfo;
/**
* @ingroup DATA_TYPE
* Network mode
*/
typedef enum
{
#if _WIZCHIP_ == 5500
NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500
#endif
NM_WAKEONLAN = (1<<5), ///< Wake On Lan
NM_PINGBLOCK = (1<<4), ///< Block ping-request
NM_PPPOE = (1<<3), ///< PPPoE mode
}netmode_type;
/**
* @ingroup DATA_TYPE
* Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation.
*/
typedef struct wiz_NetTimeout_t
{
uint8_t retry_cnt; ///< retry count
uint16_t time_100us; ///< time unit 100us
}wiz_NetTimeout;
/**
*@brief Registers call back function for critical section of I/O functions such as
*\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF.
*@param cris_en : callback function for critical section enter.
*@param cris_ex : callback function for critical section exit.
*@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions.
*@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called.
*/
void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void));
/**
*@brief Registers call back function for WIZCHIP select & deselect.
*@param cs_sel : callback function for WIZCHIP select
*@param cs_desel : callback fucntion for WIZCHIP deselect
*@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions.
*@note If you do not describe or register, null function is called.
*/
void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void));
/**
*@brief Registers call back function for bus interface.
*@param bus_rb : callback function to read byte data using system bus
*@param bus_wb : callback function to write byte data using system bus
*@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function
*or register your functions.
*@note If you do not describe or register, null function is called.
*/
void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb));
/**
*@brief Registers call back function for SPI interface.
*@param spi_rb : callback function to read byte usig SPI
*@param spi_wb : callback function to write byte usig SPI
*@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function
*or register your functions.
*@note If you do not describe or register, null function is called.
*/
void reg_wizchip_spi_cbfunc(void (*spi_rb)(uint8_t *, uint32_t), void (*spi_wb)(const uint8_t *, uint32_t));
/**
* @ingroup extra_functions
* @brief Controls to the WIZCHIP.
* @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto),
* controls interrupt & mask and so on.
* @param cwtype : Decides to the control type
* @param arg : arg type is dependent on cwtype.
* @return 0 : Success \n
* -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP
*/
int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg);
/**
* @ingroup extra_functions
* @brief Controls to network.
* @details Controls to network environment, mode, timeout and so on.
* @param cntype : Input. Decides to the control type
* @param arg : Inout. arg type is dependent on cntype.
* @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n
* 0 : Success
*/
int8_t ctlnetwork(ctlnetwork_type cntype, void* arg);
/*
* The following functions are implemented for internal use.
* but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork().
*/
/**
* @ingroup extra_functions
* @brief Reset WIZCHIP by softly.
*/
void wizchip_sw_reset(void);
/**
* @ingroup extra_functions
* @brief Initializes WIZCHIP with socket buffer size
* @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB.
* @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB.
* @return 0 : succcess \n
* -1 : fail. Invalid buffer size
*/
int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize);
/**
* @ingroup extra_functions
* @brief Clear Interrupt of WIZCHIP.
* @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
*/
void wizchip_clrinterrupt(intr_kind intr);
/**
* @ingroup extra_functions
* @brief Get Interrupt of WIZCHIP.
* @return @ref intr_kind value operated OR. It can type-cast to uint16_t.
*/
intr_kind wizchip_getinterrupt(void);
/**
* @ingroup extra_functions
* @brief Mask or Unmask Interrupt of WIZCHIP.
* @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
*/
void wizchip_setinterruptmask(intr_kind intr);
/**
* @ingroup extra_functions
* @brief Get Interrupt mask of WIZCHIP.
* @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t.
*/
intr_kind wizchip_getinterruptmask(void);
#if _WIZCHIP_ > 5100
int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100
int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100
#endif
#if _WIZCHIP_ == 5500
void wizphy_reset(void); ///< Reset phy. Vailid only in W5500
/**
* @ingroup extra_functions
* @brief Set the phy information for WIZCHIP without power mode
* @param phyconf : @ref wiz_PhyConf
*/
void wizphy_setphyconf(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief Get phy configuration information.
* @param phyconf : @ref wiz_PhyConf
*/
void wizphy_getphyconf(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief Get phy status.
* @param phyconf : @ref wiz_PhyConf
*/
void wizphy_getphystat(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200
* @param pmode Settig value of power down mode.
*/
int8_t wizphy_setphypmode(uint8_t pmode);
#endif
/**
* @ingroup extra_functions
* @brief Set the network information for WIZCHIP
* @param pnetinfo : @ref wizNetInfo
*/
void wizchip_setnetinfo(wiz_NetInfo* pnetinfo);
/**
* @ingroup extra_functions
* @brief Get the network information for WIZCHIP
* @param pnetinfo : @ref wizNetInfo
*/
void wizchip_getnetinfo(wiz_NetInfo* pnetinfo);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
uint8_t *wizchip_getsubn(void);
#endif
/**
* @ingroup extra_functions
* @brief Set the network mode such WOL, PPPoE, Ping Block, and etc.
* @param pnetinfo Value of network mode. Refer to @ref netmode_type.
*/
int8_t wizchip_setnetmode(netmode_type netmode);
/**
* @ingroup extra_functions
* @brief Get the network mode such WOL, PPPoE, Ping Block, and etc.
* @return Value of network mode. Refer to @ref netmode_type.
*/
netmode_type wizchip_getnetmode(void);
/**
* @ingroup extra_functions
* @brief Set retry time value(@ref RTR) and retry count(@ref RCR).
* @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission.
* @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout.
*/
void wizchip_settimeout(wiz_NetTimeout* nettime);
/**
* @ingroup extra_functions
* @brief Get retry time value(@ref RTR) and retry count(@ref RCR).
* @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission.
* @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout.
*/
void wizchip_gettimeout(wiz_NetTimeout* nettime);
#endif // _WIZCHIP_CONF_H_

View File

@@ -0,0 +1,978 @@
//*****************************************************************************
//
//! \file dhcp.c
//! \brief DHCP APIs implement file.
//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2013/11/18> 1st Release
//! <2012/12/20> V1.1.0
//! 1. Optimize code
//! 2. Add reg_dhcp_cbfunc()
//! 3. Add DHCP_stop()
//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run()
//! 5. Don't care system endian
//! 6. Add comments
//! <2012/12/26> V1.1.1
//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
//#include "Ethernet/socket.h"
//#include "Internet/DHCP/dhcp.h"
#include "../../Ethernet/socket.h"
#include "dhcp.h"
/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */
#ifdef _DHCP_DEBUG_
#include <stdio.h>
#endif
/* DHCP state machine. */
#define STATE_DHCP_INIT 0 ///< Initialize
#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER
#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK
#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased
#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP
#define STATE_DHCP_RELEASE 5 ///< No use
#define STATE_DHCP_STOP 6 ///< Stop processing DHCP
#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG
#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG
/* DHCP message OP code */
#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG
#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG
/* DHCP message type */
#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG
#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG
#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG
#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG
#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG
#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG
#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use
#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use
#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG
#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG
#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG
#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG
#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG
#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time
#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG
#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG
/*
* @brief DHCP option and value (cf. RFC1533)
*/
enum
{
padOption = 0,
subnetMask = 1,
timerOffset = 2,
routersOnSubnet = 3,
timeServer = 4,
nameServer = 5,
dns = 6,
logServer = 7,
cookieServer = 8,
lprServer = 9,
impressServer = 10,
resourceLocationServer = 11,
hostName = 12,
bootFileSize = 13,
meritDumpFile = 14,
domainName = 15,
swapServer = 16,
rootPath = 17,
extentionsPath = 18,
IPforwarding = 19,
nonLocalSourceRouting = 20,
policyFilter = 21,
maxDgramReasmSize = 22,
defaultIPTTL = 23,
pathMTUagingTimeout = 24,
pathMTUplateauTable = 25,
ifMTU = 26,
allSubnetsLocal = 27,
broadcastAddr = 28,
performMaskDiscovery = 29,
maskSupplier = 30,
performRouterDiscovery = 31,
routerSolicitationAddr = 32,
staticRoute = 33,
trailerEncapsulation = 34,
arpCacheTimeout = 35,
ethernetEncapsulation = 36,
tcpDefaultTTL = 37,
tcpKeepaliveInterval = 38,
tcpKeepaliveGarbage = 39,
nisDomainName = 40,
nisServers = 41,
ntpServers = 42,
vendorSpecificInfo = 43,
netBIOSnameServer = 44,
netBIOSdgramDistServer = 45,
netBIOSnodeType = 46,
netBIOSscope = 47,
xFontServer = 48,
xDisplayManager = 49,
dhcpRequestedIPaddr = 50,
dhcpIPaddrLeaseTime = 51,
dhcpOptionOverload = 52,
dhcpMessageType = 53,
dhcpServerIdentifier = 54,
dhcpParamRequest = 55,
dhcpMsg = 56,
dhcpMaxMsgSize = 57,
dhcpT1value = 58,
dhcpT2value = 59,
dhcpClassIdentifier = 60,
dhcpClientIdentifier = 61,
endOption = 255
};
/*
* @brief DHCP message format
*/
typedef struct {
uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY
uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB
uint8_t hlen; ///< @ref DHCP_HLENETHERNET
uint8_t hops; ///< @ref DHCP_HOPS
uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction.
uint16_t secs; ///< @ref DHCP_SECS
uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST
uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever
uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server
uint8_t siaddr[4]; ///< No use
uint8_t giaddr[4]; ///< No use
uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero
uint8_t sname[64]; ///< No use
uint8_t file[128]; ///< No use
uint8_t OPT[OPT_SIZE]; ///< Option
} RIP_MSG;
uint8_t DHCP_SOCKET; // Socket number for DHCP
uint8_t DHCP_SIP[4]; // DHCP Server IP address
// Network information from DHCP Server
uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address
uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP
uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP
uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP
uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP
int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state
int8_t dhcp_retry_count = 0;
uint32_t dhcp_lease_time = INFINITE_LEASETIME;
volatile uint32_t dhcp_tick_1s = 0; // unit 1 second
uint32_t dhcp_tick_next = DHCP_WAIT_TIME ;
uint32_t DHCP_XID; // Any number
RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing
uint8_t HOST_NAME[] = DCHP_HOST_NAME;
uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address.
/* The default callback function */
void default_ip_assign(void);
void default_ip_update(void);
void default_ip_conflict(void);
/* Callback handler */
void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */
void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */
void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */
void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
/* send DISCOVER message to DHCP server */
void send_DHCP_DISCOVER(void);
/* send REQEUST message to DHCP server */
void send_DHCP_REQUEST(void);
/* send DECLINE message to DHCP server */
void send_DHCP_DECLINE(void);
/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */
int8_t check_DHCP_leasedIP(void);
/* check the timeout in DHCP process */
uint8_t check_DHCP_timeout(void);
/* Intialize to timeout process. */
void reset_DHCP_timeout(void);
/* Parse message as OFFER and ACK and NACK from DHCP server.*/
int8_t parseDHCPCMSG(void);
/* The default handler of ip assign first */
void default_ip_assign(void)
{
setSIPR(DHCP_allocated_ip);
setSUBR(DHCP_allocated_sn);
setGAR (DHCP_allocated_gw);
}
/* The default handler of ip changed */
void default_ip_update(void)
{
/* WIZchip Software Reset */
setMR(MR_RST);
getMR(); // for delay
default_ip_assign();
setSHAR(DHCP_CHADDR);
}
/* The default handler of ip changed */
void default_ip_conflict(void)
{
// WIZchip Software Reset
setMR(MR_RST);
getMR(); // for delay
setSHAR(DHCP_CHADDR);
}
/* register the call back func. */
void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void))
{
dhcp_ip_assign = default_ip_assign;
dhcp_ip_update = default_ip_update;
dhcp_ip_conflict = default_ip_conflict;
if(ip_assign) dhcp_ip_assign = ip_assign;
if(ip_update) dhcp_ip_update = ip_update;
if(ip_conflict) dhcp_ip_conflict = ip_conflict;
}
/* make the common DHCP message */
void makeDHCPMSG(void)
{
uint8_t bk_mac[6];
uint8_t* ptmp;
uint8_t i;
getSHAR(bk_mac);
pDHCPMSG->op = DHCP_BOOTREQUEST;
pDHCPMSG->htype = DHCP_HTYPE10MB;
pDHCPMSG->hlen = DHCP_HLENETHERNET;
pDHCPMSG->hops = DHCP_HOPS;
ptmp = (uint8_t*)(&pDHCPMSG->xid);
*(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24);
*(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16);
*(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8);
*(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0);
pDHCPMSG->secs = DHCP_SECS;
ptmp = (uint8_t*)(&pDHCPMSG->flags);
*(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8);
*(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0);
pDHCPMSG->ciaddr[0] = 0;
pDHCPMSG->ciaddr[1] = 0;
pDHCPMSG->ciaddr[2] = 0;
pDHCPMSG->ciaddr[3] = 0;
pDHCPMSG->yiaddr[0] = 0;
pDHCPMSG->yiaddr[1] = 0;
pDHCPMSG->yiaddr[2] = 0;
pDHCPMSG->yiaddr[3] = 0;
pDHCPMSG->siaddr[0] = 0;
pDHCPMSG->siaddr[1] = 0;
pDHCPMSG->siaddr[2] = 0;
pDHCPMSG->siaddr[3] = 0;
pDHCPMSG->giaddr[0] = 0;
pDHCPMSG->giaddr[1] = 0;
pDHCPMSG->giaddr[2] = 0;
pDHCPMSG->giaddr[3] = 0;
pDHCPMSG->chaddr[0] = DHCP_CHADDR[0];
pDHCPMSG->chaddr[1] = DHCP_CHADDR[1];
pDHCPMSG->chaddr[2] = DHCP_CHADDR[2];
pDHCPMSG->chaddr[3] = DHCP_CHADDR[3];
pDHCPMSG->chaddr[4] = DHCP_CHADDR[4];
pDHCPMSG->chaddr[5] = DHCP_CHADDR[5];
for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0;
for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0;
for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0;
// MAGIC_COOKIE
pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8);
pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0;
}
/* SEND DHCP DISCOVER */
void send_DHCP_DISCOVER(void)
{
uint16_t i;
uint8_t ip[4];
uint16_t k = 0;
makeDHCPMSG();
k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
// Option Request Param
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_DISCOVER;
// Client identifier
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
// host name
pDHCPMSG->OPT[k++] = hostName;
pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname
for(i = 0 ; HOST_NAME[i] != 0; i++)
pDHCPMSG->OPT[k++] = HOST_NAME[i];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname
pDHCPMSG->OPT[k++] = dhcpParamRequest;
pDHCPMSG->OPT[k++] = 0x06; // length of request
pDHCPMSG->OPT[k++] = subnetMask;
pDHCPMSG->OPT[k++] = routersOnSubnet;
pDHCPMSG->OPT[k++] = dns;
pDHCPMSG->OPT[k++] = domainName;
pDHCPMSG->OPT[k++] = dhcpT1value;
pDHCPMSG->OPT[k++] = dhcpT2value;
pDHCPMSG->OPT[k++] = endOption;
for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
// send broadcasting packet
ip[0] = 255;
ip[1] = 255;
ip[2] = 255;
ip[3] = 255;
#ifdef _DHCP_DEBUG_
printf("> Send DHCP_DISCOVER\r\n");
#endif
sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
}
/* SEND DHCP REQUEST */
void send_DHCP_REQUEST(void)
{
int i;
uint8_t ip[4];
uint16_t k = 0;
makeDHCPMSG();
if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST)
{
*((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0];
pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1];
pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2];
pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3];
ip[0] = DHCP_SIP[0];
ip[1] = DHCP_SIP[1];
ip[2] = DHCP_SIP[2];
ip[3] = DHCP_SIP[3];
}
else
{
ip[0] = 255;
ip[1] = 255;
ip[2] = 255;
ip[3] = 255;
}
k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
// Option Request Param.
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_REQUEST;
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE)
{
pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_SIP[0];
pDHCPMSG->OPT[k++] = DHCP_SIP[1];
pDHCPMSG->OPT[k++] = DHCP_SIP[2];
pDHCPMSG->OPT[k++] = DHCP_SIP[3];
}
// host name
pDHCPMSG->OPT[k++] = hostName;
pDHCPMSG->OPT[k++] = 0; // length of hostname
for(i = 0 ; HOST_NAME[i] != 0; i++)
pDHCPMSG->OPT[k++] = HOST_NAME[i];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname
pDHCPMSG->OPT[k++] = dhcpParamRequest;
pDHCPMSG->OPT[k++] = 0x08;
pDHCPMSG->OPT[k++] = subnetMask;
pDHCPMSG->OPT[k++] = routersOnSubnet;
pDHCPMSG->OPT[k++] = dns;
pDHCPMSG->OPT[k++] = domainName;
pDHCPMSG->OPT[k++] = dhcpT1value;
pDHCPMSG->OPT[k++] = dhcpT2value;
pDHCPMSG->OPT[k++] = performRouterDiscovery;
pDHCPMSG->OPT[k++] = staticRoute;
pDHCPMSG->OPT[k++] = endOption;
for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
#ifdef _DHCP_DEBUG_
printf("> Send DHCP_REQUEST\r\n");
#endif
sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
}
/* SEND DHCP DHCPDECLINE */
void send_DHCP_DECLINE(void)
{
int i;
uint8_t ip[4];
uint16_t k = 0;
makeDHCPMSG();
k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
*((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
// Option Request Param.
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_DECLINE;
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_SIP[0];
pDHCPMSG->OPT[k++] = DHCP_SIP[1];
pDHCPMSG->OPT[k++] = DHCP_SIP[2];
pDHCPMSG->OPT[k++] = DHCP_SIP[3];
pDHCPMSG->OPT[k++] = endOption;
for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
//send broadcasting packet
ip[0] = 0xFF;
ip[1] = 0xFF;
ip[2] = 0xFF;
ip[3] = 0xFF;
#ifdef _DHCP_DEBUG_
printf("\r\n> Send DHCP_DECLINE\r\n");
#endif
sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
}
/* PARSE REPLY pDHCPMSG */
int8_t parseDHCPMSG(void)
{
uint8_t svr_addr[6];
uint16_t svr_port;
uint16_t len;
uint8_t * p;
uint8_t * e;
uint8_t type;
uint8_t opt_len;
if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0)
{
len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port);
#ifdef _DHCP_DEBUG_
printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len);
#endif
}
else return 0;
if (svr_port == DHCP_SERVER_PORT) {
// compare mac address
if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) ||
(pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) ||
(pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) )
return 0;
type = 0;
p = (uint8_t *)(&pDHCPMSG->op);
p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt)
e = p + (len - 240);
while ( p < e ) {
switch ( *p ) {
case endOption :
p = e; // for break while(p < e)
break;
case padOption :
p++;
break;
case dhcpMessageType :
p++;
p++;
type = *p++;
break;
case subnetMask :
p++;
p++;
DHCP_allocated_sn[0] = *p++;
DHCP_allocated_sn[1] = *p++;
DHCP_allocated_sn[2] = *p++;
DHCP_allocated_sn[3] = *p++;
break;
case routersOnSubnet :
p++;
opt_len = *p++;
DHCP_allocated_gw[0] = *p++;
DHCP_allocated_gw[1] = *p++;
DHCP_allocated_gw[2] = *p++;
DHCP_allocated_gw[3] = *p++;
p = p + (opt_len - 4);
break;
case dns :
p++;
opt_len = *p++;
DHCP_allocated_dns[0] = *p++;
DHCP_allocated_dns[1] = *p++;
DHCP_allocated_dns[2] = *p++;
DHCP_allocated_dns[3] = *p++;
p = p + (opt_len - 4);
break;
case dhcpIPaddrLeaseTime :
p++;
opt_len = *p++;
dhcp_lease_time = *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
#ifdef _DHCP_DEBUG_
dhcp_lease_time = 10;
#endif
break;
case dhcpServerIdentifier :
p++;
opt_len = *p++;
DHCP_SIP[0] = *p++;
DHCP_SIP[1] = *p++;
DHCP_SIP[2] = *p++;
DHCP_SIP[3] = *p++;
break;
default :
p++;
opt_len = *p++;
p += opt_len;
break;
} // switch
} // while
} // if
return type;
}
uint8_t DHCP_run(void)
{
uint8_t type;
uint8_t ret;
if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED;
if(getSn_SR(DHCP_SOCKET) != SOCK_UDP)
socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
ret = DHCP_RUNNING;
type = parseDHCPMSG();
switch ( dhcp_state ) {
case STATE_DHCP_INIT :
DHCP_allocated_ip[0] = 0;
DHCP_allocated_ip[1] = 0;
DHCP_allocated_ip[2] = 0;
DHCP_allocated_ip[3] = 0;
send_DHCP_DISCOVER();
dhcp_state = STATE_DHCP_DISCOVER;
break;
case STATE_DHCP_DISCOVER :
if (type == DHCP_OFFER){
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_OFFER\r\n");
#endif
DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];
DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];
DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];
DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];
send_DHCP_REQUEST();
dhcp_state = STATE_DHCP_REQUEST;
} else ret = check_DHCP_timeout();
break;
case STATE_DHCP_REQUEST :
if (type == DHCP_ACK) {
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_ACK\r\n");
#endif
if (check_DHCP_leasedIP()) {
// Network info assignment from DHCP
dhcp_ip_assign();
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_LEASED;
} else {
// IP address conflict occurred
reset_DHCP_timeout();
dhcp_ip_conflict();
dhcp_state = STATE_DHCP_INIT;
}
} else if (type == DHCP_NAK) {
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_NACK\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_DISCOVER;
} else ret = check_DHCP_timeout();
break;
case STATE_DHCP_LEASED :
ret = DHCP_IP_LEASED;
if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) {
#ifdef _DHCP_DEBUG_
printf("> Maintains the IP address \r\n");
#endif
type = 0;
OLD_allocated_ip[0] = DHCP_allocated_ip[0];
OLD_allocated_ip[1] = DHCP_allocated_ip[1];
OLD_allocated_ip[2] = DHCP_allocated_ip[2];
OLD_allocated_ip[3] = DHCP_allocated_ip[3];
DHCP_XID++;
send_DHCP_REQUEST();
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_REREQUEST;
}
break;
case STATE_DHCP_REREQUEST :
ret = DHCP_IP_LEASED;
if (type == DHCP_ACK) {
dhcp_retry_count = 0;
if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] ||
OLD_allocated_ip[1] != DHCP_allocated_ip[1] ||
OLD_allocated_ip[2] != DHCP_allocated_ip[2] ||
OLD_allocated_ip[3] != DHCP_allocated_ip[3])
{
ret = DHCP_IP_CHANGED;
dhcp_ip_update();
#ifdef _DHCP_DEBUG_
printf(">IP changed.\r\n");
#endif
}
#ifdef _DHCP_DEBUG_
else printf(">IP is continued.\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_LEASED;
} else if (type == DHCP_NAK) {
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_NACK, Failed to maintain ip\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_DISCOVER;
} else ret = check_DHCP_timeout();
break;
default :
break;
}
return ret;
}
void DHCP_stop(void)
{
close(DHCP_SOCKET);
dhcp_state = STATE_DHCP_STOP;
}
uint8_t check_DHCP_timeout(void)
{
uint8_t ret = DHCP_RUNNING;
if (dhcp_retry_count < MAX_DHCP_RETRY) {
if (dhcp_tick_next < dhcp_tick_1s) {
switch ( dhcp_state ) {
case STATE_DHCP_DISCOVER :
// printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n");
send_DHCP_DISCOVER();
break;
case STATE_DHCP_REQUEST :
// printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n");
send_DHCP_REQUEST();
break;
case STATE_DHCP_REREQUEST :
// printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n");
send_DHCP_REQUEST();
break;
default :
break;
}
dhcp_tick_1s = 0;
dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME;
dhcp_retry_count++;
}
} else { // timeout occurred
switch(dhcp_state) {
case STATE_DHCP_DISCOVER:
dhcp_state = STATE_DHCP_INIT;
ret = DHCP_FAILED;
break;
case STATE_DHCP_REQUEST:
case STATE_DHCP_REREQUEST:
send_DHCP_DISCOVER();
dhcp_state = STATE_DHCP_DISCOVER;
break;
default :
break;
}
reset_DHCP_timeout();
}
return ret;
}
int8_t check_DHCP_leasedIP(void)
{
uint8_t tmp;
int32_t ret;
//WIZchip RCR value changed for ARP Timeout count control
tmp = getRCR();
setRCR(0x03);
// IP conflict detection : ARP request - ARP reply
// Broadcasting ARP Request for check the IP conflict using UDP sendto() function
ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000);
// RCR value restore
setRCR(tmp);
if(ret == SOCKERR_TIMEOUT) {
// UDP send Timeout occurred : allocated IP address is unique, DHCP Success
#ifdef _DHCP_DEBUG_
printf("\r\n> Check leased IP - OK\r\n");
#endif
return 1;
} else {
// Received ARP reply or etc : IP address conflict occur, DHCP Failed
send_DHCP_DECLINE();
ret = dhcp_tick_1s;
while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message;
return 0;
}
}
void DHCP_init(uint8_t s, uint8_t * buf)
{
uint8_t zeroip[4] = {0,0,0,0};
getSHAR(DHCP_CHADDR);
if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00)
{
// assign temporary mac address, you should be set SHAR before call this function.
DHCP_CHADDR[0] = 0x00;
DHCP_CHADDR[1] = 0x08;
DHCP_CHADDR[2] = 0xdc;
DHCP_CHADDR[3] = 0x00;
DHCP_CHADDR[4] = 0x00;
DHCP_CHADDR[5] = 0x00;
setSHAR(DHCP_CHADDR);
}
DHCP_SOCKET = s; // SOCK_DHCP
pDHCPMSG = (RIP_MSG*)buf;
DHCP_XID = 0x12345678;
// WIZchip Netinfo Clear
setSIPR(zeroip);
setSIPR(zeroip);
setGAR(zeroip);
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_INIT;
}
/* Rset the DHCP timeout count and retry count. */
void reset_DHCP_timeout(void)
{
dhcp_tick_1s = 0;
dhcp_tick_next = DHCP_WAIT_TIME;
dhcp_retry_count = 0;
}
void DHCP_time_handler(void)
{
dhcp_tick_1s++;
}
void getIPfromDHCP(uint8_t* ip)
{
ip[0] = DHCP_allocated_ip[0];
ip[1] = DHCP_allocated_ip[1];
ip[2] = DHCP_allocated_ip[2];
ip[3] = DHCP_allocated_ip[3];
}
void getGWfromDHCP(uint8_t* ip)
{
ip[0] =DHCP_allocated_gw[0];
ip[1] =DHCP_allocated_gw[1];
ip[2] =DHCP_allocated_gw[2];
ip[3] =DHCP_allocated_gw[3];
}
void getSNfromDHCP(uint8_t* ip)
{
ip[0] = DHCP_allocated_sn[0];
ip[1] = DHCP_allocated_sn[1];
ip[2] = DHCP_allocated_sn[2];
ip[3] = DHCP_allocated_sn[3];
}
void getDNSfromDHCP(uint8_t* ip)
{
ip[0] = DHCP_allocated_dns[0];
ip[1] = DHCP_allocated_dns[1];
ip[2] = DHCP_allocated_dns[2];
ip[3] = DHCP_allocated_dns[3];
}
uint32_t getDHCPLeasetime(void)
{
return dhcp_lease_time;
}

View File

@@ -0,0 +1,150 @@
//*****************************************************************************
//
//! \file dhcp.h
//! \brief DHCP APIs Header file.
//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2013/11/18> 1st Release
//! <2012/12/20> V1.1.0
//! 1. Move unreferenced DEFINE to dhcp.c
//! <2012/12/26> V1.1.1
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#ifndef _DHCP_H_
#define _DHCP_H_
/*
* @brief
* @details If you want to display debug & processing message, Define _DHCP_DEBUG_
* @note If defined, it depends on <stdio.h>
*/
//#define _DHCP_DEBUG_
/* Retry to processing DHCP */
#define MAX_DHCP_RETRY 2 ///< Maximum retry count
#define DHCP_WAIT_TIME 10 ///< Wait Time 10s
/* UDP port numbers for DHCP */
#define DHCP_SERVER_PORT 67 ///< DHCP server port number
#define DHCP_CLIENT_PORT 68 ///< DHCP client port number
#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modified it any number
#define DCHP_HOST_NAME "WIZnet\0"
/*
* @brief return value of @ref DHCP_run()
*/
enum
{
DHCP_FAILED = 0, ///< Processing Fail
DHCP_RUNNING, ///< Processing DHCP protocol
DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign)
DHCP_IP_CHANGED, ///< Change IP address by new IP address from DHCP (if cbfunc == null, act as default default_ip_update)
DHCP_IP_LEASED, ///< Stand by
DHCP_STOPPED ///< Stop processing DHCP protocol
};
/*
* @brief DHCP client initialization (outside of the main loop)
* @param s - socket number
* @param buf - buffer for processing DHCP message
*/
void DHCP_init(uint8_t s, uint8_t * buf);
/*
* @brief DHCP 1s Tick Timer handler
* @note SHOULD BE register to your system 1s Tick timer handler
*/
void DHCP_time_handler(void);
/*
* @brief Register call back function
* @param ip_assign - callback func when IP is assigned from DHCP server first
* @param ip_update - callback func when IP is changed
* @prarm ip_conflict - callback func when the assigned IP is conflict with others.
*/
void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
/*
* @brief DHCP client in the main loop
* @return The value is as the follow \n
* @ref DHCP_FAILED \n
* @ref DHCP_RUNNING \n
* @ref DHCP_IP_ASSIGN \n
* @ref DHCP_IP_CHANGED \n
* @ref DHCP_IP_LEASED \n
* @ref DHCP_STOPPED \n
*
* @note This function is always called by you main task.
*/
uint8_t DHCP_run(void);
/*
* @brief Stop DHCP processing
* @note If you want to restart. call DHCP_init() and DHCP_run()
*/
void DHCP_stop(void);
/* Get Network information assigned from DHCP server */
/*
* @brief Get IP address
* @param ip - IP address to be returned
*/
void getIPfromDHCP(uint8_t* ip);
/*
* @brief Get Gateway address
* @param ip - Gateway address to be returned
*/
void getGWfromDHCP(uint8_t* ip);
/*
* @brief Get Subnet mask value
* @param ip - Subnet mask to be returned
*/
void getSNfromDHCP(uint8_t* ip);
/*
* @brief Get DNS address
* @param ip - DNS address to be returned
*/
void getDNSfromDHCP(uint8_t* ip);
/*
* @brief Get the leased time by DHCP sever
* @return unit 1s
*/
uint32_t getDHCPLeasetime(void);
#endif /* _DHCP_H_ */

View File

@@ -0,0 +1,566 @@
//*****************************************************************************
//
//! \file dns.c
//! \brief DNS APIs Implement file.
//! \details Send DNS query & Receive DNS reponse. \n
//! It depends on stdlib.h & string.h in ansi-c library
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.1.0
//! 1. Remove secondary DNS server in DNS_run
//! If 1st DNS_run failed, call DNS_run with 2nd DNS again
//! 2. DNS_timerHandler -> DNS_time_handler
//! 3. Remove the unused define
//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c
//! <2013/12/20> V1.1.0
//!
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include <string.h>
#include <stdlib.h>
//#include "Ethernet/socket.h"
//#include "Internet/DNS/dns.h"
#include "../../ethernet/socket.h"
#include "dns.h"
#ifdef _DNS_DEBUG_
#include <stdio.h>
#endif
#define INITRTT 2000L /* Initial smoothed response time */
#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */
#define TYPE_A 1 /* Host address */
#define TYPE_NS 2 /* Name server */
#define TYPE_MD 3 /* Mail destination (obsolete) */
#define TYPE_MF 4 /* Mail forwarder (obsolete) */
#define TYPE_CNAME 5 /* Canonical name */
#define TYPE_SOA 6 /* Start of Authority */
#define TYPE_MB 7 /* Mailbox name (experimental) */
#define TYPE_MG 8 /* Mail group member (experimental) */
#define TYPE_MR 9 /* Mail rename name (experimental) */
#define TYPE_NULL 10 /* Null (experimental) */
#define TYPE_WKS 11 /* Well-known sockets */
#define TYPE_PTR 12 /* Pointer record */
#define TYPE_HINFO 13 /* Host information */
#define TYPE_MINFO 14 /* Mailbox information (experimental)*/
#define TYPE_MX 15 /* Mail exchanger */
#define TYPE_TXT 16 /* Text strings */
#define TYPE_ANY 255 /* Matches any type */
#define CLASS_IN 1 /* The ARPA Internet */
/* Round trip timing parameters */
#define AGAIN 8 /* Average RTT gain = 1/8 */
#define LAGAIN 3 /* Log2(AGAIN) */
#define DGAIN 4 /* Mean deviation gain = 1/4 */
#define LDGAIN 2 /* log2(DGAIN) */
/* Header for all domain messages */
struct dhdr
{
uint16_t id; /* Identification */
uint8_t qr; /* Query/Response */
#define QUERY 0
#define RESPONSE 1
uint8_t opcode;
#define IQUERY 1
uint8_t aa; /* Authoratative answer */
uint8_t tc; /* Truncation */
uint8_t rd; /* Recursion desired */
uint8_t ra; /* Recursion available */
uint8_t rcode; /* Response code */
#define NO_ERROR 0
#define FORMAT_ERROR 1
#define SERVER_FAIL 2
#define NAME_ERROR 3
#define NOT_IMPL 4
#define REFUSED 5
uint16_t qdcount; /* Question count */
uint16_t ancount; /* Answer count */
uint16_t nscount; /* Authority (name server) count */
uint16_t arcount; /* Additional record count */
};
uint8_t* pDNSMSG; // DNS message buffer
uint8_t DNS_SOCKET; // SOCKET number for DNS
uint16_t DNS_MSGID; // DNS message ID
extern uint32_t HAL_GetTick(void);
uint32_t hal_sys_tick;
/* converts uint16_t from network buffer to a host byte order integer. */
uint16_t get16(uint8_t * s)
{
uint16_t i;
i = *s++ << 8;
i = i + *s;
return i;
}
/* copies uint16_t to the network buffer with network byte order. */
uint8_t * put16(uint8_t * s, uint16_t i)
{
*s++ = i >> 8;
*s++ = i;
return s;
}
/*
* CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM
*
* Description : This function converts a compressed domain name to the human-readable form
* Arguments : msg - is a pointer to the reply message
* compressed - is a pointer to the domain name in reply message.
* buf - is a pointer to the buffer for the human-readable form name.
* len - is the MAX. size of buffer.
* Returns : the length of compressed message
*/
int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len)
{
uint16_t slen; /* Length of current segment */
uint8_t * cp;
int clen = 0; /* Total length of compressed name */
int indirect = 0; /* Set if indirection encountered */
int nseg = 0; /* Total number of segments in name */
cp = compressed;
for (;;)
{
slen = *cp++; /* Length of this segment */
if (!indirect) clen++;
if ((slen & 0xc0) == 0xc0)
{
if (!indirect)
clen++;
indirect = 1;
/* Follow indirection */
cp = &msg[((slen & 0x3f)<<8) + *cp];
slen = *cp++;
}
if (slen == 0) /* zero length == all done */
break;
len -= slen + 1;
if (len < 0) return -1;
if (!indirect) clen += slen;
while (slen-- != 0) *buf++ = (char)*cp++;
*buf++ = '.';
nseg++;
}
if (nseg == 0)
{
/* Root name; represent as single dot */
*buf++ = '.';
len--;
}
*buf++ = '\0';
len--;
return clen; /* Length of compressed message */
}
/*
* PARSE QUESTION SECTION
*
* Description : This function parses the question record of the reply message.
* Arguments : msg - is a pointer to the reply message
* cp - is a pointer to the question record.
* Returns : a pointer the to next record.
*/
uint8_t * dns_question(uint8_t * msg, uint8_t * cp)
{
int len;
char name[MAXCNAME];
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
cp += 2; /* type */
cp += 2; /* class */
return cp;
}
/*
* PARSE ANSER SECTION
*
* Description : This function parses the answer record of the reply message.
* Arguments : msg - is a pointer to the reply message
* cp - is a pointer to the answer record.
* Returns : a pointer the to next record.
*/
uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns)
{
int len, type;
char name[MAXCNAME];
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
type = get16(cp);
cp += 2; /* type */
cp += 2; /* class */
cp += 4; /* ttl */
cp += 2; /* len */
switch (type)
{
case TYPE_A:
/* Just read the address directly into the structure */
ip_from_dns[0] = *cp++;
ip_from_dns[1] = *cp++;
ip_from_dns[2] = *cp++;
ip_from_dns[3] = *cp++;
break;
case TYPE_CNAME:
case TYPE_MB:
case TYPE_MG:
case TYPE_MR:
case TYPE_NS:
case TYPE_PTR:
/* These types all consist of a single domain name */
/* convert it to ASCII format */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
break;
case TYPE_HINFO:
len = *cp++;
cp += len;
len = *cp++;
cp += len;
break;
case TYPE_MX:
cp += 2;
/* Get domain name of exchanger */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
break;
case TYPE_SOA:
/* Get domain name of name server */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
/* Get domain name of responsible person */
len = parse_name(msg, cp, name, MAXCNAME);
if (len == -1) return 0;
cp += len;
cp += 4;
cp += 4;
cp += 4;
cp += 4;
cp += 4;
break;
case TYPE_TXT:
/* Just stash */
break;
default:
/* Ignore */
break;
}
return cp;
}
/*
* PARSE THE DNS REPLY
*
* Description : This function parses the reply message from DNS server.
* Arguments : dhdr - is a pointer to the header for DNS message
* buf - is a pointer to the reply message.
* len - is the size of reply message.
* Returns : -1 - Domain name length is too big
* 0 - Fail (Timeout or parse error)
* 1 - Success,
*/
int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns)
{
uint16_t tmp;
uint16_t i;
uint8_t * msg;
uint8_t * cp;
msg = pbuf;
memset(pdhdr, 0, sizeof(*pdhdr));
pdhdr->id = get16(&msg[0]);
tmp = get16(&msg[2]);
if (tmp & 0x8000) pdhdr->qr = 1;
pdhdr->opcode = (tmp >> 11) & 0xf;
if (tmp & 0x0400) pdhdr->aa = 1;
if (tmp & 0x0200) pdhdr->tc = 1;
if (tmp & 0x0100) pdhdr->rd = 1;
if (tmp & 0x0080) pdhdr->ra = 1;
pdhdr->rcode = tmp & 0xf;
pdhdr->qdcount = get16(&msg[4]);
pdhdr->ancount = get16(&msg[6]);
pdhdr->nscount = get16(&msg[8]);
pdhdr->arcount = get16(&msg[10]);
/* Now parse the variable length sections */
cp = &msg[12];
/* Question section */
for (i = 0; i < pdhdr->qdcount; i++)
{
cp = dns_question(msg, cp);
if(!cp)
{
#ifdef _DNS_DEBUG_
printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n");
#endif
return -1;
}
}
/* Answer section */
for (i = 0; i < pdhdr->ancount; i++)
{
cp = dns_answer(msg, cp, ip_from_dns);
if(!cp)
{
#ifdef _DNS_DEBUG_
printf("MAX_DOMAIN_NAME is too small, it should be redefined in dns.h\r\n");
#endif
return -1;
}
}
/* Name server (authority) section */
for (i = 0; i < pdhdr->nscount; i++)
{
;
}
/* Additional section */
for (i = 0; i < pdhdr->arcount; i++)
{
;
}
if(pdhdr->rcode == 0) return 1; // No error
else return 0;
}
/*
* MAKE DNS QUERY MESSAGE
*
* Description : This function makes DNS query message.
* Arguments : op - Recursion desired
* name - is a pointer to the domain name.
* buf - is a pointer to the buffer for DNS message.
* len - is the MAX. size of buffer.
* Returns : the pointer to the DNS message.
*/
int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len)
{
uint8_t *cp;
char *cp1;
char sname[MAXCNAME];
char *dname;
uint16_t p;
uint16_t dlen;
cp = buf;
DNS_MSGID++;
cp = put16(cp, DNS_MSGID);
p = (op << 11) | 0x0100; /* Recursion desired */
cp = put16(cp, p);
cp = put16(cp, 1);
cp = put16(cp, 0);
cp = put16(cp, 0);
cp = put16(cp, 0);
strcpy(sname, name);
dname = sname;
dlen = strlen(dname);
for (;;)
{
/* Look for next dot */
cp1 = strchr(dname, '.');
if (cp1 != NULL) len = cp1 - dname; /* More to come */
else len = dlen; /* Last component */
*cp++ = len; /* Write length of component */
if (len == 0) break;
/* Copy component up to (but not including) dot */
memcpy(cp, dname, len);
cp += len;
if (cp1 == NULL)
{
*cp++ = 0; /* Last one; write null and finish */
break;
}
dname += len+1;
dlen -= len+1;
}
cp = put16(cp, 0x0001); /* type */
cp = put16(cp, 0x0001); /* class */
return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf)));
}
/*
* CHECK DNS TIMEOUT
*
* Description : This function check the DNS timeout
* Arguments : None.
* Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur
* Note : timeout : retry count and timer both over.
*/
int8_t check_DNS_timeout(void)
{
static uint8_t retry_count;
uint32_t tick = HAL_GetTick();
if(tick - hal_sys_tick >= DNS_WAIT_TIME * 1000)
{
hal_sys_tick = tick;
if(retry_count >= MAX_DNS_RETRY) {
retry_count = 0;
return -1; // timeout occurred
}
retry_count++;
return 0; // timer over, but no timeout
}
return 1; // no timer over, no timeout occur
}
/* DNS CLIENT INIT */
void DNS_init(uint8_t s, uint8_t * buf)
{
DNS_SOCKET = s; // SOCK_DNS
pDNSMSG = buf; // User's shared buffer
DNS_MSGID = DNS_MSG_ID;
}
/* DNS CLIENT RUN */
int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns)
{
int8_t ret;
struct dhdr dhp;
uint8_t ip[4];
uint16_t len, port;
int8_t ret_check_timeout;
hal_sys_tick = HAL_GetTick();
// Socket open
WIZCHIP_EXPORT(socket)(DNS_SOCKET, Sn_MR_UDP, 0, 0);
#ifdef _DNS_DEBUG_
printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
#endif
len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE);
WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
while (1)
{
if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0)
{
if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE;
len = WIZCHIP_EXPORT(recvfrom)(DNS_SOCKET, pDNSMSG, len, ip, &port);
#ifdef _DNS_DEBUG_
printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len);
#endif
ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns);
break;
}
// Check Timeout
ret_check_timeout = check_DNS_timeout();
if (ret_check_timeout < 0) {
#ifdef _DNS_DEBUG_
printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
#endif
return 0; // timeout occurred
}
else if (ret_check_timeout == 0) {
#ifdef _DNS_DEBUG_
printf("> DNS Timeout\r\n");
#endif
WIZCHIP_EXPORT(sendto)(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
}
}
WIZCHIP_EXPORT(close)(DNS_SOCKET);
// Return value
// 0 > : failed / 1 - success
return ret;
}

View File

@@ -0,0 +1,96 @@
//*****************************************************************************
//
//! \file dns.h
//! \brief DNS APIs Header file.
//! \details Send DNS query & Receive DNS reponse.
//! \version 1.1.0
//! \date 2013/11/18
//! \par Revision history
//! <2013/10/21> 1st Release
//! <2013/12/20> V1.1.0
//! 1. Remove secondary DNS server in DNS_run
//! If 1st DNS_run failed, call DNS_run with 2nd DNS again
//! 2. DNS_timerHandler -> DNS_time_handler
//! 3. Move the no reference define to dns.c
//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c
//! <2013/12/20> V1.1.0
//!
//! \author Eric Jung & MidnightCow
//! \copyright
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#ifndef _DNS_H_
#define _DNS_H_
#include <stdint.h>
/*
* @brief Define it for Debug & Monitor DNS processing.
* @note If defined, it depends on <stdio.h>
*/
//#define _DNS_DEBUG_
#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */
/*
* @brief Maximum length of your queried Domain name
* @todo SHOULD BE defined it equal as or greater than your Domain name length + null character(1)
* @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack.
*/
#define MAX_DOMAIN_NAME 32 // for example "www.google.com"
#define MAX_DNS_RETRY 2 ///< Requery Count
#define DNS_WAIT_TIME 4 ///< Wait response time. unit 1s.
#define IPPORT_DOMAIN 53 ///< DNS server port number
#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modified it any number
/*
* @brief DNS process initialize
* @param s : Socket number for DNS
* @param buf : Buffer for DNS message
*/
void DNS_init(uint8_t s, uint8_t * buf);
/*
* @brief DNS process
* @details Send DNS query and receive DNS response
* @param dns_ip : DNS server ip address
* @param name : Domain name to be queried
* @param ip_from_dns : IP address from DNS server
* @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n
* 0 : failed (Timeout or Parse error)\n
* 1 : success
* @note This function blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME
*/
int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns);
#endif /* _DNS_H_ */

View File

@@ -1,7 +1,9 @@
#import essential libraries
import lcd
import pyb
lcd = pyb.LCD('x')
lcd.light(1)
# do 1 iteration of Conway's Game of Life
def conway_step():
for x in range(128): # loop over x coordinates
@@ -21,26 +23,24 @@ def conway_step():
# apply the rules of life
if self and not (2 <= num_neighbours <= 3):
lcd.reset(x, y) # not enough, or too many neighbours: cell dies
lcd.pixel(x, y, 0) # not enough, or too many neighbours: cell dies
elif not self and num_neighbours == 3:
lcd.set(x, y) # exactly 3 neigbours around an empty cell: cell is born
lcd.pixel(x, y, 1) # exactly 3 neigbours around an empty cell: cell is born
# randomise the start
def conway_rand():
lcd.clear() # clear the LCD
lcd.fill(0) # clear the LCD
for x in range(128): # loop over x coordinates
for y in range(32): # loop over y coordinates
if pyb.rand() & 1: # get a 1-bit random number
lcd.set(x, y) # set the pixel randomly
lcd.pixel(x, y, pyb.rng() & 1) # set the pixel randomly
# loop for a certain number of frames, doing iterations of Conway's Game of Life
def conway_go(num_frames):
for i in range(num_frames):
conway_step() # do 1 iteration
lcd.show() # update the LCD
pyb.delay(300)
pyb.delay(50)
# PC testing
lcd = lcd.LCD(128, 32)
# testing
conway_rand()
conway_go(1000)
conway_go(100)

View File

@@ -1,36 +0,0 @@
# LCD testing object for PC
# uses double buffering
class LCD:
def __init__(self, width, height):
self.width = width
self.height = height
self.buf1 = [[0 for x in range(self.width)] for y in range(self.height)]
self.buf2 = [[0 for x in range(self.width)] for y in range(self.height)]
def clear(self):
for y in range(self.height):
for x in range(self.width):
self.buf1[y][x] = self.buf2[y][x] = 0
def show(self):
print('') # blank line to separate frames
for y in range(self.height):
for x in range(self.width):
self.buf1[y][x] = self.buf2[y][x]
for y in range(self.height):
row = ''.join(['*' if self.buf1[y][x] else ' ' for x in range(self.width)])
print(row)
def get(self, x, y):
if 0 <= x < self.width and 0 <= y < self.height:
return self.buf1[y][x]
else:
return 0
def reset(self, x, y):
if 0 <= x < self.width and 0 <= y < self.height:
self.buf2[y][x] = 0
def set(self, x, y):
if 0 <= x < self.width and 0 <= y < self.height:
self.buf2[y][x] = 1

58
examples/pins.py Normal file
View File

@@ -0,0 +1,58 @@
# Print a nice list of pins, their current settings, and available afs.
# Requires pins_af.py from stmhal/build-PYBV10/ directory.
import pyb
import pins_af
def af():
max_name_width = 0
max_af_width = 0
for pin_entry in pins_af.PINS_AF:
max_name_width = max(max_name_width, len(pin_entry[0]))
for af_entry in pin_entry[1:]:
max_af_width = max(max_af_width, len(af_entry[1]))
for pin_entry in pins_af.PINS_AF:
pin_name = pin_entry[0]
print('%-*s ' % (max_name_width, pin_name), end='')
for af_entry in pin_entry[1:]:
print('%2d: %-*s ' % (af_entry[0], max_af_width, af_entry[1]), end='')
print('')
def pins():
mode_str = { pyb.Pin.IN : 'IN',
pyb.Pin.OUT_PP : 'OUT_PP',
pyb.Pin.OUT_OD : 'OUT_OD',
pyb.Pin.AF_PP : 'AF_PP',
pyb.Pin.AF_OD : 'AF_OD',
pyb.Pin.ANALOG : 'ANALOG' }
pull_str = { pyb.Pin.PULL_NONE : '',
pyb.Pin.PULL_UP : 'PULL_UP',
pyb.Pin.PULL_DOWN : 'PULL_DOWN' }
width = [0, 0, 0, 0]
rows = []
for pin_entry in pins_af.PINS_AF:
row = []
pin_name = pin_entry[0]
pin = pyb.Pin(pin_name)
pin_mode = pin.mode()
row.append(pin_name)
row.append(mode_str[pin_mode])
row.append(pull_str[pin.pull()])
if pin_mode == pyb.Pin.AF_PP or pin_mode == pyb.Pin.AF_OD:
pin_af = pin.af()
for af_entry in pin_entry[1:]:
if pin_af == af_entry[0]:
af_str = '%d: %s' % (pin_af, af_entry[1])
break
else:
af_str = '%d' % pin_af
else:
af_str = ''
row.append(af_str)
for col in range(len(width)):
width[col] = max(width[col], len(row[col]))
rows.append(row)
for row in rows:
for col in range(len(width)):
print('%-*s ' % (width[col], row[col]), end='')
print('')

View File

@@ -6,8 +6,44 @@ def delay(n):
pass
rand_seed = 1
def rand():
def rng():
global rand_seed
# for these choice of numbers, see P L'Ecuyer, "Tables of linear congruential generators of different sizes and good lattice structure"
rand_seed = (rand_seed * 653276) % 8388593
return rand_seed
# LCD testing object for PC
# uses double buffering
class LCD:
def __init__(self, port):
self.width = 128
self.height = 32
self.buf1 = [[0 for x in range(self.width)] for y in range(self.height)]
self.buf2 = [[0 for x in range(self.width)] for y in range(self.height)]
def light(self, value):
pass
def fill(self, value):
for y in range(self.height):
for x in range(self.width):
self.buf1[y][x] = self.buf2[y][x] = value
def show(self):
print('') # blank line to separate frames
for y in range(self.height):
for x in range(self.width):
self.buf1[y][x] = self.buf2[y][x]
for y in range(self.height):
row = ''.join(['*' if self.buf1[y][x] else ' ' for x in range(self.width)])
print(row)
def get(self, x, y):
if 0 <= x < self.width and 0 <= y < self.height:
return self.buf1[y][x]
else:
return 0
def pixel(self, x, y, value):
if 0 <= x < self.width and 0 <= y < self.height:
self.buf2[y][x] = value

View File

@@ -1,5 +1,5 @@
try:
import microsocket as _socket
import usocket as _socket
except:
import _socket

View File

@@ -1,5 +1,5 @@
try:
import microsocket as socket
import usocket as socket
except:
import socket

View File

@@ -1,592 +0,0 @@
/* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32 checking (inflate-only subset of miniz.c)
See "unlicense" statement at the end of this file.
Rich Geldreich <richgel99@gmail.com>, last updated May 20, 2011
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
The entire decompressor coroutine is implemented in tinfl_decompress(). The other functions are optional high-level helpers.
*/
#ifndef TINFL_HEADER_INCLUDED
#define TINFL_HEADER_INCLUDED
#include <stdlib.h>
typedef unsigned char mz_uint8;
typedef signed short mz_int16;
typedef unsigned short mz_uint16;
typedef unsigned int mz_uint32;
typedef unsigned int mz_uint;
typedef unsigned long long mz_uint64;
#if defined(_M_IX86) || defined(_M_X64)
// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster).
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
#define MINIZ_LITTLE_ENDIAN 1
#endif
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
// Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator)
#define MINIZ_HAS_64BIT_REGISTERS 1
#endif
// Works around MSVC's spammy "warning C4127: conditional expression is constant" message.
#ifdef _MSC_VER
#define MZ_MACRO_END while (0, 0)
#else
#define MZ_MACRO_END while (0)
#endif
// Decompression flags used by tinfl_decompress().
// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
enum
{
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
TINFL_FLAG_HAS_MORE_INPUT = 2,
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
TINFL_FLAG_COMPUTE_ADLER32 = 8
};
// High level decompression functions:
// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
// On entry:
// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
// On return:
// Function returns a pointer to the decompressed data, or NULL on failure.
// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
// The caller must free() the returned block when it's no longer needed.
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
// Returns 1 on success or 0 on failure.
typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
// Max size of LZ dictionary.
#define TINFL_LZ_DICT_SIZE 32768
// Return status.
typedef enum
{
TINFL_STATUS_BAD_PARAM = -3,
TINFL_STATUS_ADLER32_MISMATCH = -2,
TINFL_STATUS_FAILED = -1,
TINFL_STATUS_DONE = 0,
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
TINFL_STATUS_HAS_MORE_OUTPUT = 2
} tinfl_status;
// Initializes the decompressor to its initial state.
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
#define tinfl_get_adler32(r) (r)->m_check_adler32
// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
// Internal/private bits follow.
enum
{
TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
};
typedef struct
{
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
} tinfl_huff_table;
#if MINIZ_HAS_64BIT_REGISTERS
#define TINFL_USE_64BIT_BITBUF 1
#endif
#if TINFL_USE_64BIT_BITBUF
typedef mz_uint64 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (64)
#else
typedef mz_uint32 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (32)
#endif
struct tinfl_decompressor_tag
{
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
tinfl_bit_buf_t m_bit_buf;
size_t m_dist_from_out_buf_start;
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
};
#endif // #ifdef TINFL_HEADER_INCLUDED
// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
#ifndef TINFL_HEADER_FILE_ONLY
#include <string.h>
// MZ_MALLOC, etc. are only used by the optional high-level helper functions.
#ifdef MINIZ_NO_MALLOC
#define MZ_MALLOC(x) NULL
#define MZ_FREE(x) x, ((void)0)
#define MZ_REALLOC(p, x) NULL
#else
#define MZ_MALLOC(x) malloc(x)
#define MZ_FREE(x) free(x)
#define MZ_REALLOC(p, x) realloc(p, x)
#endif
#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
#else
#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
#endif
#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
#define TINFL_MEMSET(p, c, l) memset(p, c, l)
#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
#define TINFL_CR_FINISH }
// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never
// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
#define TINFL_GET_BYTE(state_index, c) do { \
if (pIn_buf_cur >= pIn_buf_end) { \
for ( ; ; ) { \
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
if (pIn_buf_cur < pIn_buf_end) { \
c = *pIn_buf_cur++; \
break; \
} \
} else { \
c = 0; \
break; \
} \
} \
} else c = *pIn_buf_cur++; } MZ_MACRO_END
#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a
// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the
// bit buffer contains >=15 bits (deflate's max. Huffman code size).
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
do { \
temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
if (temp >= 0) { \
code_len = temp >> 9; \
if ((code_len) && (num_bits >= code_len)) \
break; \
} else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
code_len = TINFL_FAST_LOOKUP_BITS; \
do { \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
} TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
} while (num_bits < 15);
// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read
// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully
// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32.
// The slow path is only executed at the very end of the input buffer.
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
int temp; mz_uint code_len, c; \
if (num_bits < 15) { \
if ((pIn_buf_end - pIn_buf_cur) < 2) { \
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
} else { \
bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
} \
} \
if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
code_len = temp >> 9, temp &= 511; \
else { \
code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
} sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
{
static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 };
static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
static const int s_min_table_sizes[3] = { 257, 1, 4 };
tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
// Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter).
if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
TINFL_CR_BEGIN
bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
{
TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
}
do
{
TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
if (r->m_type == 0)
{
TINFL_SKIP_BITS(5, num_bits & 7);
for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
while ((counter) && (num_bits))
{
TINFL_GET_BITS(51, dist, 8);
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = (mz_uint8)dist;
counter--;
}
while (counter)
{
size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
while (pIn_buf_cur >= pIn_buf_end)
{
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
{
TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
}
else
{
TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
}
}
n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
}
}
else if (r->m_type == 3)
{
TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
}
else
{
if (r->m_type == 1)
{
mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
}
else
{
for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
r->m_table_sizes[2] = 19;
}
for ( ; (int)r->m_type >= 0; r->m_type--)
{
int tree_next, tree_cur; tinfl_huff_table *pTable;
mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
if ((65536 != total) && (used_syms > 1))
{
TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
}
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
{
mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
{
tree_cur -= ((rev_code >>= 1) & 1);
if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1];
}
tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
}
if (r->m_type == 2)
{
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
{
mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
if ((dist == 16) && (!counter))
{
TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
}
num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
}
if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
{
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
}
TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
}
}
for ( ; ; )
{
mz_uint8 *pSrc;
for ( ; ; )
{
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
{
TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
if (counter >= 256)
break;
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = (mz_uint8)counter;
}
else
{
int sym2; mz_uint code_len;
#if TINFL_USE_64BIT_BITBUF
if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
#else
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
}
counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
if (counter & 256)
break;
#if !TINFL_USE_64BIT_BITBUF
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
}
bit_buf >>= code_len; num_bits -= code_len;
pOut_buf_cur[0] = (mz_uint8)counter;
if (sym2 & 256)
{
pOut_buf_cur++;
counter = sym2;
break;
}
pOut_buf_cur[1] = (mz_uint8)sym2;
pOut_buf_cur += 2;
}
}
if ((counter &= 511) == 256) break;
num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
{
TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
}
pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
{
while (counter--)
{
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
}
continue;
}
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
else if ((counter >= 9) && (counter <= dist))
{
const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
do
{
((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
pOut_buf_cur += 8;
} while ((pSrc += 8) < pSrc_end);
if ((counter &= 7) < 3)
{
if (counter)
{
pOut_buf_cur[0] = pSrc[0];
if (counter > 1)
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur += counter;
}
continue;
}
}
#endif
do
{
pOut_buf_cur[0] = pSrc[0];
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur[2] = pSrc[2];
pOut_buf_cur += 3; pSrc += 3;
} while ((int)(counter -= 3) > 2);
if ((int)counter > 0)
{
pOut_buf_cur[0] = pSrc[0];
if ((int)counter > 1)
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur += counter;
}
}
}
} while (!(r->m_final & 1));
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
{
TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
}
TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
TINFL_CR_FINISH
common_exit:
r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
*pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
{
const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
while (buf_len)
{
for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
{
s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
}
for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
}
r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
}
return status;
}
// Higher level helper functions.
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
{
tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
*pOut_len = 0;
tinfl_init(&decomp);
for ( ; ; )
{
size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size,
(flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
{
MZ_FREE(pBuf); *pOut_len = 0; return NULL;
}
src_buf_ofs += src_buf_size;
*pOut_len += dst_buf_size;
if (status == TINFL_STATUS_DONE) break;
new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
if (!pNew_buf)
{
MZ_FREE(pBuf); *pOut_len = 0; return NULL;
}
pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
}
return pBuf;
}
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
{
tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
}
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
int result = 0;
tinfl_decompressor decomp;
mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
if (!pDict)
return TINFL_STATUS_FAILED;
tinfl_init(&decomp);
for ( ; ; )
{
size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
(flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
in_buf_ofs += in_buf_size;
if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
break;
if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
{
result = (status == TINFL_STATUS_DONE);
break;
}
dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
}
MZ_FREE(pDict);
*pIn_buf_size = in_buf_ofs;
return result;
}
#endif // #ifndef TINFL_HEADER_FILE_ONLY
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
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 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.
For more information, please refer to <http://unlicense.org/>
*/

View File

@@ -119,7 +119,7 @@ STATIC NORETURN void syntax_error() {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "syntax error in uctypes descriptor"));
}
STATIC mp_obj_t uctypes_struct_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
STATIC mp_obj_t uctypes_struct_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
if (n_args < 2 || n_args > 3) {
syntax_error();
}
@@ -261,10 +261,10 @@ STATIC inline mp_obj_t get_unaligned(uint val_type, void *p, int big_endian) {
}
}
STATIC inline void set_unaligned(uint val_type, void *p, int big_endian, mp_obj_t val) {
STATIC inline void set_unaligned(uint val_type, byte *p, int big_endian, mp_obj_t val) {
char struct_type = big_endian ? '>' : '<';
static const char type2char[8] = "BbHhIiQq";
mp_binary_set_val(struct_type, type2char[val_type], val, (byte**)&p);
mp_binary_set_val(struct_type, type2char[val_type], val, &p);
}
static inline mp_uint_t get_aligned_basic(uint val_type, void *p) {
@@ -309,10 +309,12 @@ STATIC mp_obj_t get_aligned(uint val_type, void *p, mp_int_t index) {
case UINT64:
case INT64:
return mp_obj_new_int_from_ll(((int64_t*)p)[index]);
#if MICROPY_PY_BUILTINS_FLOAT
case FLOAT32:
return mp_obj_new_float(((float*)p)[index]);
case FLOAT64:
return mp_obj_new_float(((double*)p)[index]);
#endif
default:
assert(0);
return MP_OBJ_NULL;
@@ -399,7 +401,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
set_aligned_basic(val_type & 6, self->addr + offset, val);
} else {
mp_binary_set_int(GET_SCALAR_SIZE(val_type & 7), self->flags == LAYOUT_BIG_ENDIAN,
self->addr + offset, (byte*)&val);
self->addr + offset, val);
}
return set_val; // just !MP_OBJ_NULL
}

279
extmod/modujson.c Normal file
View File

@@ -0,0 +1,279 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "mpconfig.h"
#include "misc.h"
#include "nlr.h"
#include "qstr.h"
#include "obj.h"
#include "objlist.h"
#include "parsenum.h"
#include "runtime.h"
#if MICROPY_PY_UJSON
STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
vstr_t vstr;
vstr_init(&vstr, 8);
mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, &vstr, obj, PRINT_JSON);
mp_obj_t ret = mp_obj_new_str(vstr.buf, vstr.len, false);
vstr_clear(&vstr);
return ret;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
// This function implements a simple non-recursive JSON parser.
//
// The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt
// The parser here will parse any valid JSON and return the correct
// corresponding Python object. It allows through a superset of JSON, since
// it treats commas and colons as "whitespace", and doesn't care if
// brackets/braces are correctly paired. It will raise a ValueError if the
// input is outside it's specs.
//
// Most of the work is parsing the primitives (null, false, true, numbers,
// strings). It does 1 pass over the input string and so is easily extended to
// being able to parse from a non-seekable stream. It tries to be fast and
// small in code size, while not using more RAM than necessary.
STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
mp_uint_t len;
const char *s = mp_obj_str_get_data(obj, &len);
const char *top = s + len;
vstr_t vstr;
vstr_init(&vstr, 8);
mp_obj_list_t stack; // we use a list as a simple stack for nested JSON
stack.len = 0;
stack.items = NULL;
mp_obj_t stack_top = MP_OBJ_NULL;
mp_obj_type_t *stack_top_type = NULL;
mp_obj_t stack_key = MP_OBJ_NULL;
for (;;) {
cont:
if (s == top) {
break;
}
mp_obj_t next = MP_OBJ_NULL;
bool enter = false;
switch (*s) {
case ',':
case ':':
case ' ':
s += 1;
goto cont;
case 'n':
if (s + 3 < top && s[1] == 'u' && s[2] == 'l' && s[3] == 'l') {
s += 4;
next = mp_const_none;
} else {
goto fail;
}
break;
case 'f':
if (s + 4 < top && s[1] == 'a' && s[2] == 'l' && s[3] == 's' && s[4] == 'e') {
s += 5;
next = mp_const_false;
} else {
goto fail;
}
break;
case 't':
if (s + 3 < top && s[1] == 'r' && s[2] == 'u' && s[3] == 'e') {
s += 4;
next = mp_const_true;
} else {
goto fail;
}
break;
case '"':
vstr_reset(&vstr);
for (s++; s < top && *s != '"';) {
byte c = *s;
if (c == '\\') {
s++;
c = *s;
switch (c) {
case 'b': c = 0x08; break;
case 'f': c = 0x0c; break;
case 'n': c = 0x0a; break;
case 'r': c = 0x0d; break;
case 't': c = 0x09; break;
case 'u': {
if (s + 4 >= top) { goto fail; }
mp_uint_t num = 0;
for (int i = 0; i < 4; i++) {
c = (*++s | 0x20) - '0';
if (c > 9) {
c -= ('a' - ('9' + 1));
}
num = (num << 4) | c;
}
vstr_add_char(&vstr, num);
goto str_cont;
}
}
}
vstr_add_byte(&vstr, c);
str_cont:
s++;
}
if (s == top) {
goto fail;
}
s++;
next = mp_obj_new_str(vstr.buf, vstr.len, false);
break;
case '-':
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {
bool flt = false;
vstr_reset(&vstr);
for (; s < top; s++) {
if (*s == '.' || *s == 'E' || *s == 'e') {
flt = true;
} else if (*s == '-' || unichar_isdigit(*s)) {
// pass
} else {
break;
}
vstr_add_byte(&vstr, *s);
}
if (flt) {
next = mp_parse_num_decimal(vstr.buf, vstr.len, false, false);
} else {
next = mp_parse_num_integer(vstr.buf, vstr.len, 10);
}
break;
}
case '[':
next = mp_obj_new_list(0, NULL);
enter = true;
s += 1;
break;
case '{':
next = mp_obj_new_dict(0);
enter = true;
s += 1;
break;
case '}':
case ']': {
s += 1;
if (stack_top == MP_OBJ_NULL) {
// no object at all
goto fail;
}
if (stack.len == 0) {
// finished; compound object
goto success;
}
stack.len -= 1;
stack_top = stack.items[stack.len];
stack_top_type = mp_obj_get_type(stack_top);
goto cont;
}
default:
goto fail;
}
if (stack_top == MP_OBJ_NULL) {
stack_top = next;
stack_top_type = mp_obj_get_type(stack_top);
if (!enter) {
// finished; single primitive only
goto success;
}
} else {
// append to list or dict
if (stack_top_type == &mp_type_list) {
mp_obj_list_append(stack_top, next);
} else {
if (stack_key == MP_OBJ_NULL) {
stack_key = next;
if (enter) {
goto fail;
}
} else {
mp_obj_dict_store(stack_top, stack_key, next);
stack_key = MP_OBJ_NULL;
}
}
if (enter) {
if (stack.items == NULL) {
mp_obj_list_init(&stack, 1);
stack.items[0] = stack_top;
} else {
mp_obj_list_append(&stack, stack_top);
}
stack_top = next;
stack_top_type = mp_obj_get_type(stack_top);
}
}
}
success:
// eat trailing whitespace
while (s < top && unichar_isspace(*s)) {
s++;
}
if (s < top) {
// unexpected chars
goto fail;
}
if (stack.len != 0) {
goto fail;
}
vstr_clear(&vstr);
return stack_top;
fail:
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "syntax error in JSON"));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads);
STATIC const mp_map_elem_t mp_module_ujson_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ujson) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_dumps), (mp_obj_t)&mod_ujson_dumps_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_loads), (mp_obj_t)&mod_ujson_loads_obj },
};
STATIC const mp_obj_dict_t mp_module_ujson_globals = {
.base = {&mp_type_dict},
.map = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = MP_ARRAY_SIZE(mp_module_ujson_globals_table),
.alloc = MP_ARRAY_SIZE(mp_module_ujson_globals_table),
.table = (mp_map_elem_t*)mp_module_ujson_globals_table,
},
};
const mp_obj_module_t mp_module_ujson = {
.base = { &mp_type_module },
.name = MP_QSTR_ujson,
.globals = (mp_obj_dict_t*)&mp_module_ujson_globals,
};
#endif //MICROPY_PY_UJSON

250
extmod/modure.c Normal file
View File

@@ -0,0 +1,250 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include "binary.h"
#if MICROPY_PY_URE
#include "re1.5/re1.5.h"
#define FLAG_DEBUG 0x1000
typedef struct _mp_obj_re_t {
mp_obj_base_t base;
ByteProg re;
} mp_obj_re_t;
typedef struct _mp_obj_match_t {
mp_obj_base_t base;
int num_matches;
mp_obj_t str;
const char *caps[0];
} mp_obj_match_t;
STATIC void match_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_match_t *self = self_in;
print(env, "<match num=%d @%p>", self->num_matches);
}
STATIC mp_obj_t match_group(mp_obj_t self_in, mp_obj_t no_in) {
mp_obj_match_t *self = self_in;
mp_int_t no = mp_obj_int_get(no_in);
if (no < 0 || no >= self->num_matches / 2) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_IndexError, no_in));
}
const char *start = self->caps[no * 2];
return mp_obj_new_str(start, self->caps[no * 2 + 1] - start, false);
}
MP_DEFINE_CONST_FUN_OBJ_2(match_group_obj, match_group);
STATIC const mp_map_elem_t match_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_group), (mp_obj_t) &match_group_obj },
};
STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table);
STATIC const mp_obj_type_t match_type = {
{ &mp_type_type },
.name = MP_QSTR_match,
.print = match_print,
.locals_dict = (mp_obj_t)&match_locals_dict,
};
STATIC void re_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_re_t *self = self_in;
print(env, "<re %p>", self);
}
STATIC mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
mp_obj_re_t *self = args[0];
Subject subj;
mp_uint_t len;
subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len;
int caps_num = (self->re.sub + 1) * 2;
mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char*, caps_num);
int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, is_anchored);
if (res == 0) {
m_del_var(mp_obj_match_t, char*, caps_num, match);
return mp_const_none;
}
match->base.type = &match_type;
match->num_matches = caps_num;
match->str = args[1];
return match;
}
STATIC mp_obj_t re_match(uint n_args, const mp_obj_t *args) {
return re_exec(true, n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_match_obj, 2, 4, re_match);
STATIC mp_obj_t re_search(uint n_args, const mp_obj_t *args) {
return re_exec(false, n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_search_obj, 2, 4, re_search);
STATIC mp_obj_t re_split(uint n_args, const mp_obj_t *args) {
mp_obj_re_t *self = args[0];
Subject subj;
mp_uint_t len;
subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len;
int caps_num = (self->re.sub + 1) * 2;
int maxsplit = 0;
if (n_args > 2) {
maxsplit = mp_obj_int_get(args[2]);
}
mp_obj_t retval = mp_obj_new_list(0, NULL);
const char *caps[caps_num];
while (true) {
int res = re1_5_recursiveloopprog(&self->re, &subj, caps, caps_num, false);
// if we didn't have a match, or had an empty match, it's time to stop
if (!res || caps[0] == caps[1]) {
break;
}
mp_obj_t s = mp_obj_new_str(subj.begin, caps[0] - subj.begin, false);
mp_obj_list_append(retval, s);
if (self->re.sub > 0) {
mp_not_implemented("Splitting with sub-captures");
}
subj.begin = caps[1];
if (maxsplit > 0 && --maxsplit == 0) {
break;
}
}
mp_obj_t s = mp_obj_new_str(subj.begin, subj.end - subj.begin, false);
mp_obj_list_append(retval, s);
return retval;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split);
STATIC const mp_map_elem_t re_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_match), (mp_obj_t) &re_match_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_search), (mp_obj_t) &re_search_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_split), (mp_obj_t) &re_split_obj },
};
STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table);
STATIC const mp_obj_type_t re_type = {
{ &mp_type_type },
.name = MP_QSTR_ure,
.print = re_print,
.locals_dict = (mp_obj_t)&re_locals_dict,
};
mp_obj_t mod_re_compile(uint n_args, const mp_obj_t *args) {
const char *re_str = mp_obj_str_get_str(args[0]);
int size = re1_5_sizecode(re_str);
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
o->base.type = &re_type;
int flags = 0;
if (n_args > 1) {
flags = mp_obj_get_int(args[1]);
}
int error = re1_5_compilecode(&o->re, re_str);
if (error != 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Error in regex"));
}
if (flags & FLAG_DEBUG) {
re1_5_dumpcode(&o->re);
}
return o;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile);
STATIC mp_obj_t mod_re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
mp_obj_re_t *self = mod_re_compile(1, args);
const mp_obj_t args2[] = {self, args[1]};
mp_obj_match_t *match = re_exec(is_anchored, 2, args2);
return match;
}
STATIC mp_obj_t mod_re_match(uint n_args, const mp_obj_t *args) {
return mod_re_exec(true, n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_match_obj, 2, 4, mod_re_match);
STATIC mp_obj_t mod_re_search(uint n_args, const mp_obj_t *args) {
return mod_re_exec(false, n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_search_obj, 2, 4, mod_re_search);
STATIC const mp_map_elem_t mp_module_re_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ure) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_compile), (mp_obj_t)&mod_re_compile_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_match), (mp_obj_t)&mod_re_match_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_search), (mp_obj_t)&mod_re_search_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_DEBUG), MP_OBJ_NEW_SMALL_INT(FLAG_DEBUG) },
};
STATIC const mp_obj_dict_t mp_module_re_globals = {
.base = {&mp_type_dict},
.map = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = MP_ARRAY_SIZE(mp_module_re_globals_table),
.alloc = MP_ARRAY_SIZE(mp_module_re_globals_table),
.table = (mp_map_elem_t*)mp_module_re_globals_table,
},
};
const mp_obj_module_t mp_module_ure = {
.base = { &mp_type_module },
.name = MP_QSTR_ure,
.globals = (mp_obj_dict_t*)&mp_module_re_globals,
};
// Source files #include'd here to make sure they're compiled in
// only if module is enabled by config setting.
#define re1_5_fatal(x) assert(!x)
#include "re1.5/compilecode.c"
#include "re1.5/dumpcode.c"
#include "re1.5/recursiveloop.c"
#include "re1.5/charclass.c"
#endif //MICROPY_PY_URE

114
extmod/moduzlib.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <math.h>
#include "mpconfig.h"
#include "misc.h"
#include "qstr.h"
#include "nlr.h"
#include "obj.h"
#include "runtime.h"
#if MICROPY_PY_UZLIB
#include "uzlib/tinf.h"
#if 0 // print debugging info
#define DEBUG_printf DEBUG_printf
#else // don't print debugging info
#define DEBUG_printf(...) (void)0
#endif
STATIC int mod_uzlib_grow_buf(TINF_DATA *d, unsigned alloc_req) {
if (alloc_req < 256) {
alloc_req = 256;
}
DEBUG_printf("uzlib: Resizing buffer to " UINT_FMT " bytes\n", d->destSize + alloc_req);
d->destStart = m_renew(byte, d->destStart, d->destSize, d->destSize + alloc_req);
d->destSize += alloc_req;
return 0;
}
STATIC mp_obj_t mod_uzlib_decompress(mp_uint_t n_args, const mp_obj_t *args) {
mp_obj_t data = args[0];
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
TINF_DATA *decomp = m_new_obj(TINF_DATA);
DEBUG_printf("sizeof(TINF_DATA)=" UINT_FMT "\n", sizeof(*decomp));
decomp->destStart = m_new(byte, bufinfo.len);
decomp->destSize = bufinfo.len;
decomp->destGrow = mod_uzlib_grow_buf;
decomp->source = bufinfo.buf;
int st = tinf_zlib_uncompress_dyn(decomp, bufinfo.len);
if (st != 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_ValueError, MP_OBJ_NEW_SMALL_INT(st)));
}
mp_obj_t res = mp_obj_new_bytearray_by_ref(decomp->dest - decomp->destStart, decomp->destStart);
m_del_obj(TINF_DATA, decomp);
return res;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_uzlib_decompress_obj, 1, 3, mod_uzlib_decompress);
STATIC const mp_map_elem_t mp_module_uzlib_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uzlib) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_decompress), (mp_obj_t)&mod_uzlib_decompress_obj },
};
STATIC const mp_obj_dict_t mp_module_uzlib_globals = {
.base = {&mp_type_dict},
.map = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = MP_ARRAY_SIZE(mp_module_uzlib_globals_table),
.alloc = MP_ARRAY_SIZE(mp_module_uzlib_globals_table),
.table = (mp_map_elem_t*)mp_module_uzlib_globals_table,
},
};
const mp_obj_module_t mp_module_uzlib = {
.base = { &mp_type_module },
.name = MP_QSTR_uzlib,
.globals = (mp_obj_dict_t*)&mp_module_uzlib_globals,
};
// Source files #include'd here to make sure they're compiled in
// only if module is enabled by config setting.
#include "uzlib/tinflate.c"
#include "uzlib/tinfzlib.c"
#include "uzlib/adler32.c"
#endif // MICROPY_PY_UZLIB

View File

@@ -1,108 +0,0 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <math.h>
#include "mpconfig.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#if MICROPY_PY_ZLIBD
#include "miniz/tinfl.c"
#if 0 // print debugging info
#define DEBUG_printf DEBUG_printf
#else // don't print debugging info
#define DEBUG_printf(...) (void)0
#endif
STATIC mp_obj_t mod_zlibd_decompress(uint n_args, mp_obj_t *args) {
mp_obj_t data = args[0];
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
tinfl_decompressor *decomp = m_new_obj(tinfl_decompressor);
tinfl_init(decomp);
DEBUG_printf("sizeof(tinfl_decompressor)=%d\n", sizeof(tinfl_decompressor));
byte *out = m_new(byte, bufinfo.len);
size_t out_len = bufinfo.len;
size_t in_buf_ofs = 0, dst_buf_ofs = 0;
size_t dst_buf_sz = bufinfo.len;
while (1) {
size_t in_buf_sz = bufinfo.len - in_buf_ofs;
DEBUG_printf("tinfl in: in_ofs=%d in_sz=%d dst_ofs=%d, dst_sz=%d\n", in_buf_ofs, in_buf_sz, dst_buf_ofs, dst_buf_sz);
tinfl_status st = tinfl_decompress(decomp,
bufinfo.buf + in_buf_ofs, &in_buf_sz,
out, out + dst_buf_ofs, &dst_buf_sz,
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | TINFL_FLAG_PARSE_ZLIB_HEADER);
DEBUG_printf("tinfl out: st=%d, in_sz=%d, out_sz=%d\n", st, in_buf_sz, dst_buf_sz);
in_buf_ofs += in_buf_sz;
dst_buf_ofs += dst_buf_sz;
if (st != TINFL_STATUS_HAS_MORE_OUTPUT) {
break;
}
out = m_renew(byte, out, out_len, dst_buf_ofs + 256);
out_len = dst_buf_ofs + 256;
dst_buf_sz = out_len - dst_buf_ofs;
}
m_del_obj(tinfl_decompressor, decomp);
return mp_obj_new_bytearray_by_ref(dst_buf_ofs, out);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_zlibd_decompress_obj, 1, 3, mod_zlibd_decompress);
STATIC const mp_map_elem_t mp_module_zlibd_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_zlibd) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_decompress), (mp_obj_t)&mod_zlibd_decompress_obj },
};
STATIC const mp_obj_dict_t mp_module_zlibd_globals = {
.base = {&mp_type_dict},
.map = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = MP_ARRAY_SIZE(mp_module_zlibd_globals_table),
.alloc = MP_ARRAY_SIZE(mp_module_zlibd_globals_table),
.table = (mp_map_elem_t*)mp_module_zlibd_globals_table,
},
};
const mp_obj_module_t mp_module_zlibd = {
.base = { &mp_type_module },
.name = MP_QSTR_zlibd,
.globals = (mp_obj_dict_t*)&mp_module_zlibd_globals,
};
#endif //MICROPY_PY_ZLIBD

13
extmod/re1.5/charclass.c Normal file
View File

@@ -0,0 +1,13 @@
#include "re1.5.h"
int _re1_5_classmatch(const char *pc, const char *sp)
{
// pc points to "cnt" byte after opcode
int is_positive = (pc[-1] == Class);
int cnt = *pc++;
while (cnt--) {
if (*sp >= *pc && *sp <= pc[1]) return is_positive;
pc += 2;
}
return !is_positive;
}

249
extmod/re1.5/compilecode.c Normal file
View File

@@ -0,0 +1,249 @@
// Copyright 2014 Paul Sokolovsky.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "re1.5.h"
static void insert_code(char *code, int at, int num, int *pc)
{
memmove(code + at + num, code + at, *pc - at);
*pc += num;
}
#define REL(at, to) (to - at - 2)
int re1_5_sizecode(const char *re)
{
int pc = 5 + NON_ANCHORED_PREFIX; // Save 0, Save 1, Match; more bytes for "search" (vs "match") prefix code
for (; *re; re++) {
switch (*re) {
case '\\':
re++;
default:
pc += 2;
break;
case '+':
// Skip entire "+?"
if (re[1] == '?')
re++;
case '?':
pc += 2;
break;
case '.':
case '^':
case '$':
pc++;
break;
case '*':
// Skip entire "*?"
if (re[1] == '?')
re++;
case '|':
case '(':
pc += 4;
break;
case ')':
break;
case '[': {
pc += 2;
re++;
if (*re == '^') re++;
while (*re != ']') {
if (!*re) return -1;
if (re[1] == '-') {
re += 2;
}
pc += 2;
re++;
}
}
}
}
return pc;
}
#define EMIT(at, byte) code[at] = byte
const char *_compilecode(const char *re, ByteProg *prog)
{
char *code = prog->insts;
int pc = prog->bytelen;
int start = pc;
int term = pc;
int alt_label = 0;
for (; *re && *re != ')'; re++) {
switch (*re) {
case '\\':
re++;
default:
term = pc;
EMIT(pc++, Char);
EMIT(pc++, *re);
prog->len++;
break;
case '.':
term = pc;
EMIT(pc++, Any);
prog->len++;
break;
case '[': {
int cnt;
term = pc;
re++;
if (*re == '^') {
EMIT(pc++, ClassNot);
re++;
} else {
EMIT(pc++, Class);
}
pc++; // Skip # of pair byte
prog->len++;
for (cnt = 0; *re != ']'; re++, cnt++) {
if (!*re) return NULL;
EMIT(pc++, *re);
if (re[1] == '-') {
re += 2;
}
EMIT(pc++, *re);
}
EMIT(term + 1, cnt);
break;
}
case '(':
term = pc;
EMIT(pc++, Save);
EMIT(pc++, 2 * ++prog->sub);
prog->len++;
prog->bytelen = pc;
re = _compilecode(re + 1, prog);
pc = prog->bytelen;
EMIT(pc++, Save);
EMIT(pc++, 2 * prog->sub + 1);
prog->len++;
break;
case '?':
insert_code(code, term, 2, &pc);
EMIT(term, Split);
EMIT(term + 1, REL(term, pc));
prog->len++;
break;
case '*':
insert_code(code, term, 2, &pc);
EMIT(pc, Jmp);
EMIT(pc + 1, REL(pc, term));
pc += 2;
if (re[1] == '?') {
EMIT(term, RSplit);
re++;
} else {
EMIT(term, Split);
}
EMIT(term + 1, REL(term, pc));
prog->len += 2;
break;
case '+':
if (re[1] == '?') {
EMIT(pc, Split);
re++;
} else {
EMIT(pc, RSplit);
}
EMIT(pc + 1, REL(pc, term));
pc += 2;
prog->len++;
break;
case '|':
if (alt_label) {
EMIT(alt_label, REL(alt_label, pc) + 1);
}
insert_code(code, start, 2, &pc);
EMIT(pc++, Jmp);
alt_label = pc++;
EMIT(start, Split);
EMIT(start + 1, REL(start, pc));
prog->len += 2;
break;
case '^':
EMIT(pc++, Bol);
prog->len++;
break;
case '$':
EMIT(pc++, Eol);
prog->len++;
break;
}
}
if (alt_label) {
EMIT(alt_label, REL(alt_label, pc) + 1);
}
prog->bytelen = pc;
return re;
}
int re1_5_compilecode(ByteProg *prog, const char *re)
{
prog->len = 0;
prog->bytelen = 0;
prog->sub = 0;
// Add code to implement non-anchored operation ("search"),
// for anchored operation ("match"), this code will be just skipped.
// TODO: Implement search in much more efficient manner
prog->insts[prog->bytelen++] = RSplit;
prog->insts[prog->bytelen++] = 3;
prog->insts[prog->bytelen++] = Any;
prog->insts[prog->bytelen++] = Jmp;
prog->insts[prog->bytelen++] = -5;
prog->len += 3;
prog->insts[prog->bytelen++] = Save;
prog->insts[prog->bytelen++] = 0;
prog->len++;
_compilecode(re, prog);
prog->insts[prog->bytelen++] = Save;
prog->insts[prog->bytelen++] = 1;
prog->len++;
prog->insts[prog->bytelen++] = Match;
prog->len++;
return 0;
}
void
cleanmarks(ByteProg *prog)
{
char *pc = prog->insts;
char *end = pc + prog->bytelen;
while (pc < end) {
*pc &= 0x7f;
switch (*pc) {
case Jmp:
case Split:
case RSplit:
case Save:
case Char:
pc++;
}
pc++;
}
}
#if 0
int main(int argc, char *argv[])
{
int pc = 0;
ByteProg *code = re1_5_compilecode(argv[1]);
re1_5_dumpcode(code);
}
#endif

62
extmod/re1.5/dumpcode.c Normal file
View File

@@ -0,0 +1,62 @@
// Copyright 2014 Paul Sokolovsky.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "re1.5.h"
void re1_5_dumpcode(ByteProg *prog)
{
int pc = 0;
char *code = prog->insts;
while (pc < prog->bytelen) {
printf("%2d: ", pc);
switch(code[pc++]) {
default:
assert(0);
// re1_5_fatal("printprog");
case Split:
printf("split %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]);
pc++;
break;
case RSplit:
printf("rsplit %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]);
pc++;
break;
case Jmp:
printf("jmp %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]);
pc++;
break;
case Char:
printf("char %c\n", code[pc++]);
break;
case Any:
printf("any\n");
break;
case Class:
case ClassNot: {
int num = code[pc];
printf("class%s %d", (code[pc - 1] == ClassNot ? "not" : ""), num);
pc++;
while (num--) {
printf(" 0x%02x-0x%02x", code[pc], code[pc + 1]);
pc += 2;
}
printf("\n");
break;
}
case Match:
printf("match\n");
break;
case Save:
printf("save %d\n", (unsigned char)code[pc++]);
break;
case Bol:
printf("assert bol\n");
break;
case Eol:
printf("assert eol\n");
break;
}
}
printf("Bytes: %d, insts: %d\n", prog->bytelen, prog->len);
}

149
extmod/re1.5/re1.5.h Normal file
View File

@@ -0,0 +1,149 @@
// Copyright 2007-2009 Russ Cox. All Rights Reserved.
// Copyright 2014 Paul Sokolovsky.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#ifndef _RE1_5_REGEXP__H
#define _RE1_5_REGEXP__H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#define nil ((void*)0)
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
typedef struct Regexp Regexp;
typedef struct Prog Prog;
typedef struct ByteProg ByteProg;
typedef struct Inst Inst;
typedef struct Subject Subject;
struct Regexp
{
int type;
int n;
int ch;
Regexp *left;
Regexp *right;
};
enum /* Regexp.type */
{
Alt = 1,
Cat,
Lit,
Dot,
Paren,
Quest,
Star,
Plus,
};
Regexp *parse(char*);
Regexp *reg(int type, Regexp *left, Regexp *right);
void printre(Regexp*);
#ifndef re1_5_fatal
void re1_5_fatal(char*);
#endif
void *mal(int);
struct Prog
{
Inst *start;
int len;
};
struct ByteProg
{
int bytelen;
int len;
int sub;
char insts[0];
};
struct Inst
{
int opcode;
int c;
int n;
Inst *x;
Inst *y;
int gen; // global state, oooh!
};
enum /* Inst.opcode */
{
// Instructions which consume input bytes (and thus fail if none left)
CONSUMERS = 1,
Char = CONSUMERS,
Any,
Class,
ClassNot,
ASSERTS = 0x50,
Bol = ASSERTS,
Eol,
// Instructions which take relative offset as arg
JUMPS = 0x60,
Jmp = JUMPS,
Split,
RSplit,
// Other (special) instructions
Save = 0x7e,
Match = 0x7f,
};
#define inst_is_consumer(inst) ((inst) < ASSERTS)
#define inst_is_jump(inst) ((inst) & 0x70 == JUMPS)
Prog *compile(Regexp*);
void printprog(Prog*);
extern int gen;
enum {
MAXSUB = 20
};
typedef struct Sub Sub;
struct Sub
{
int ref;
int nsub;
const char *sub[MAXSUB];
};
Sub *newsub(int n);
Sub *incref(Sub*);
Sub *copy(Sub*);
Sub *update(Sub*, int, const char*);
void decref(Sub*);
struct Subject {
const char *begin;
const char *end;
};
#define NON_ANCHORED_PREFIX 5
#define HANDLE_ANCHORED(bytecode, is_anchored) ((is_anchored) ? (bytecode) + NON_ANCHORED_PREFIX : (bytecode))
int re1_5_backtrack(ByteProg*, Subject*, const char**, int, int);
int re1_5_pikevm(ByteProg*, Subject*, const char**, int, int);
int re1_5_recursiveloopprog(ByteProg*, Subject*, const char**, int, int);
int re1_5_recursiveprog(ByteProg*, Subject*, const char**, int, int);
int re1_5_thompsonvm(ByteProg*, Subject*, const char**, int, int);
int re1_5_sizecode(const char *re);
int re1_5_compilecode(ByteProg *prog, const char *re);
void re1_5_dumpcode(ByteProg *prog);
void cleanmarks(ByteProg *prog);
int _re1_5_classmatch(const char *pc, const char *sp);
#endif /*_RE1_5_REGEXP__H*/

View File

@@ -0,0 +1,78 @@
// Copyright 2007-2009 Russ Cox. All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "re1.5.h"
static int
recursiveloop(char *pc, const char *sp, Subject *input, const char **subp, int nsubp)
{
const char *old;
int off;
for(;;) {
if(inst_is_consumer(*pc)) {
// If we need to match a character, but there's none left, it's fail
if(sp >= input->end)
return 0;
}
switch(*pc++) {
case Char:
if(*sp != *pc++)
return 0;
case Any:
sp++;
continue;
case Class:
case ClassNot:
if (!_re1_5_classmatch(pc, sp))
return 0;
pc += *(unsigned char*)pc * 2 + 1;
sp++;
continue;
case Match:
return 1;
case Jmp:
off = (signed char)*pc++;
pc = pc + off;
continue;
case Split:
off = (signed char)*pc++;
if(recursiveloop(pc, sp, input, subp, nsubp))
return 1;
pc = pc + off;
continue;
case RSplit:
off = (signed char)*pc++;
if(recursiveloop(pc + off, sp, input, subp, nsubp))
return 1;
continue;
case Save:
off = (unsigned char)*pc++;
if(off >= nsubp) {
continue;
}
old = subp[off];
subp[off] = sp;
if(recursiveloop(pc, sp, input, subp, nsubp))
return 1;
subp[off] = old;
return 0;
case Bol:
if(sp != input->begin)
return 0;
continue;
case Eol:
if(sp != input->end)
return 0;
continue;
}
re1_5_fatal("recursiveloop");
}
}
int
re1_5_recursiveloopprog(ByteProg *prog, Subject *input, const char **subp, int nsubp, int is_anchored)
{
return recursiveloop(HANDLE_ANCHORED(prog->insts, is_anchored), input->begin, input, subp, nsubp);
}

78
extmod/uzlib/adler32.c Normal file
View File

@@ -0,0 +1,78 @@
/*
* Adler-32 checksum
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
/*
* Adler-32 algorithm taken from the zlib source, which is
* Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
*/
#include "tinf.h"
#define A32_BASE 65521
#define A32_NMAX 5552
unsigned int tinf_adler32(const void *data, unsigned int length)
{
const unsigned char *buf = (const unsigned char *)data;
unsigned int s1 = 1;
unsigned int s2 = 0;
while (length > 0)
{
int k = length < A32_NMAX ? length : A32_NMAX;
int i;
for (i = k / 16; i; --i, buf += 16)
{
s1 += buf[0]; s2 += s1; s1 += buf[1]; s2 += s1;
s1 += buf[2]; s2 += s1; s1 += buf[3]; s2 += s1;
s1 += buf[4]; s2 += s1; s1 += buf[5]; s2 += s1;
s1 += buf[6]; s2 += s1; s1 += buf[7]; s2 += s1;
s1 += buf[8]; s2 += s1; s1 += buf[9]; s2 += s1;
s1 += buf[10]; s2 += s1; s1 += buf[11]; s2 += s1;
s1 += buf[12]; s2 += s1; s1 += buf[13]; s2 += s1;
s1 += buf[14]; s2 += s1; s1 += buf[15]; s2 += s1;
}
for (i = k % 16; i; --i) { s1 += *buf++; s2 += s1; }
s1 %= A32_BASE;
s2 %= A32_BASE;
length -= k;
}
return (s2 << 16) | s1;
}

102
extmod/uzlib/tinf.h Normal file
View File

@@ -0,0 +1,102 @@
/*
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014 by Paul Sokolovsky
*/
#ifndef TINF_H_INCLUDED
#define TINF_H_INCLUDED
#include <stdint.h>
/* calling convention */
#ifndef TINFCC
#ifdef __WATCOMC__
#define TINFCC __cdecl
#else
#define TINFCC
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define TINF_OK 0
#define TINF_DATA_ERROR (-3)
#define TINF_DEST_OVERFLOW (-4)
/* data structures */
typedef struct {
unsigned short table[16]; /* table of code length counts */
unsigned short trans[288]; /* code -> symbol translation table */
} TINF_TREE;
struct TINF_DATA;
typedef struct TINF_DATA {
const unsigned char *source;
unsigned int tag;
unsigned int bitcount;
/* Buffer start */
unsigned char *destStart;
/* Buffer total size */
unsigned int destSize;
/* Current pointer in buffer */
unsigned char *dest;
/* Remaining bytes in buffer */
unsigned int destRemaining;
/* Argument is the allocation size which didn't fit into buffer. Note that
exact mimumum size to grow buffer by is lastAlloc - destRemaining. But
growing by this exact size is ineficient, as the next allocation will
fail again. */
int (*destGrow)(struct TINF_DATA *data, unsigned int lastAlloc);
TINF_TREE ltree; /* dynamic length/symbol tree */
TINF_TREE dtree; /* dynamic distance tree */
} TINF_DATA;
/* low-level API */
/* Step 1: Allocate TINF_DATA structure */
/* Step 2: Set destStart, destSize, and destGrow fields */
/* Step 3: Set source field */
/* Step 4: Call tinf_uncompress_dyn() */
/* Step 5: In response to destGrow callback, update destStart and destSize fields */
/* Step 6: When tinf_uncompress_dyn() returns, buf.dest points to a byte past last uncompressed byte */
int TINFCC tinf_uncompress_dyn(TINF_DATA *d);
int TINFCC tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen);
/* high-level API */
void TINFCC tinf_init();
int TINFCC tinf_uncompress(void *dest, unsigned int *destLen,
const void *source, unsigned int sourceLen);
int TINFCC tinf_gzip_uncompress(void *dest, unsigned int *destLen,
const void *source, unsigned int sourceLen);
int TINFCC tinf_zlib_uncompress(void *dest, unsigned int *destLen,
const void *source, unsigned int sourceLen);
unsigned int TINFCC tinf_adler32(const void *data, unsigned int length);
unsigned int TINFCC tinf_crc32(const void *data, unsigned int length);
/* compression API */
void TINFCC tinf_compress(void *data, const uint8_t *src, unsigned slen);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* TINF_H_INCLUDED */

511
extmod/uzlib/tinflate.c Normal file
View File

@@ -0,0 +1,511 @@
/*
* tinflate - tiny inflate
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014 by Paul Sokolovsky
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include "tinf.h"
/* --------------------------------------------------- *
* -- uninitialized global data (static structures) -- *
* --------------------------------------------------- */
#ifdef RUNTIME_BITS_TABLES
/* extra bits and base tables for length codes */
unsigned char length_bits[30];
unsigned short length_base[30];
/* extra bits and base tables for distance codes */
unsigned char dist_bits[30];
unsigned short dist_base[30];
#else
const unsigned char length_bits[30] = {
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5
};
const unsigned short length_base[30] = {
3, 4, 5, 6, 7, 8, 9, 10,
11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115,
131, 163, 195, 227, 258
};
const unsigned char dist_bits[30] = {
0, 0, 0, 0, 1, 1, 2, 2,
3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10,
11, 11, 12, 12, 13, 13
};
const unsigned short dist_base[30] = {
1, 2, 3, 4, 5, 7, 9, 13,
17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073,
4097, 6145, 8193, 12289, 16385, 24577
};
#endif
/* special ordering of code length codes */
const unsigned char clcidx[] = {
16, 17, 18, 0, 8, 7, 9, 6,
10, 5, 11, 4, 12, 3, 13, 2,
14, 1, 15
};
/* ----------------------- *
* -- utility functions -- *
* ----------------------- */
/* Execute callback to grow destination buffer */
static int tinf_grow_dest_buf(TINF_DATA *d, unsigned int lastAlloc)
{
unsigned int oldsize = d->dest - d->destStart;
/* This will update only destStart and destSize */
if (!d->destGrow)
{
return TINF_DEST_OVERFLOW;
}
d->destGrow(d, lastAlloc);
d->dest = d->destStart + oldsize;
d->destRemaining = d->destSize - oldsize;
return 0;
}
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
static void tinf_build_bits_base(unsigned char *bits, unsigned short *base, int delta, int first)
{
int i, sum;
/* build bits table */
for (i = 0; i < delta; ++i) bits[i] = 0;
for (i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta;
/* build base table */
for (sum = first, i = 0; i < 30; ++i)
{
base[i] = sum;
sum += 1 << bits[i];
}
}
#endif
/* build the fixed huffman trees */
static void tinf_build_fixed_trees(TINF_TREE *lt, TINF_TREE *dt)
{
int i;
/* build fixed length tree */
for (i = 0; i < 7; ++i) lt->table[i] = 0;
lt->table[7] = 24;
lt->table[8] = 152;
lt->table[9] = 112;
for (i = 0; i < 24; ++i) lt->trans[i] = 256 + i;
for (i = 0; i < 144; ++i) lt->trans[24 + i] = i;
for (i = 0; i < 8; ++i) lt->trans[24 + 144 + i] = 280 + i;
for (i = 0; i < 112; ++i) lt->trans[24 + 144 + 8 + i] = 144 + i;
/* build fixed distance tree */
for (i = 0; i < 5; ++i) dt->table[i] = 0;
dt->table[5] = 32;
for (i = 0; i < 32; ++i) dt->trans[i] = i;
}
/* given an array of code lengths, build a tree */
static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned int num)
{
unsigned short offs[16];
unsigned int i, sum;
/* clear code length count table */
for (i = 0; i < 16; ++i) t->table[i] = 0;
/* scan symbol lengths, and sum code length counts */
for (i = 0; i < num; ++i) t->table[lengths[i]]++;
t->table[0] = 0;
/* compute offset table for distribution sort */
for (sum = 0, i = 0; i < 16; ++i)
{
offs[i] = sum;
sum += t->table[i];
}
/* create code->symbol translation table (symbols sorted by code) */
for (i = 0; i < num; ++i)
{
if (lengths[i]) t->trans[offs[lengths[i]]++] = i;
}
}
/* ---------------------- *
* -- decode functions -- *
* ---------------------- */
/* get one bit from source stream */
static int tinf_getbit(TINF_DATA *d)
{
unsigned int bit;
/* check if tag is empty */
if (!d->bitcount--)
{
/* load next tag */
d->tag = *d->source++;
d->bitcount = 7;
}
/* shift bit out of tag */
bit = d->tag & 0x01;
d->tag >>= 1;
return bit;
}
/* read a num bit value from a stream and add base */
static unsigned int tinf_read_bits(TINF_DATA *d, int num, int base)
{
unsigned int val = 0;
/* read num bits */
if (num)
{
unsigned int limit = 1 << (num);
unsigned int mask;
for (mask = 1; mask < limit; mask *= 2)
if (tinf_getbit(d)) val += mask;
}
return val + base;
}
/* given a data stream and a tree, decode a symbol */
static int tinf_decode_symbol(TINF_DATA *d, TINF_TREE *t)
{
int sum = 0, cur = 0, len = 0;
/* get more bits while code value is above sum */
do {
cur = 2*cur + tinf_getbit(d);
++len;
sum += t->table[len];
cur -= t->table[len];
} while (cur >= 0);
return t->trans[sum + cur];
}
/* given a data stream, decode dynamic trees from it */
static void tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
unsigned char lengths[288+32];
unsigned int hlit, hdist, hclen;
unsigned int i, num, length;
/* get 5 bits HLIT (257-286) */
hlit = tinf_read_bits(d, 5, 257);
/* get 5 bits HDIST (1-32) */
hdist = tinf_read_bits(d, 5, 1);
/* get 4 bits HCLEN (4-19) */
hclen = tinf_read_bits(d, 4, 4);
for (i = 0; i < 19; ++i) lengths[i] = 0;
/* read code lengths for code length alphabet */
for (i = 0; i < hclen; ++i)
{
/* get 3 bits code length (0-7) */
unsigned int clen = tinf_read_bits(d, 3, 0);
lengths[clcidx[i]] = clen;
}
/* build code length tree, temporarily use length tree */
tinf_build_tree(lt, lengths, 19);
/* decode code lengths for the dynamic trees */
for (num = 0; num < hlit + hdist; )
{
int sym = tinf_decode_symbol(d, lt);
switch (sym)
{
case 16:
/* copy previous code length 3-6 times (read 2 bits) */
{
unsigned char prev = lengths[num - 1];
for (length = tinf_read_bits(d, 2, 3); length; --length)
{
lengths[num++] = prev;
}
}
break;
case 17:
/* repeat code length 0 for 3-10 times (read 3 bits) */
for (length = tinf_read_bits(d, 3, 3); length; --length)
{
lengths[num++] = 0;
}
break;
case 18:
/* repeat code length 0 for 11-138 times (read 7 bits) */
for (length = tinf_read_bits(d, 7, 11); length; --length)
{
lengths[num++] = 0;
}
break;
default:
/* values 0-15 represent the actual code lengths */
lengths[num++] = sym;
break;
}
}
/* build dynamic trees */
tinf_build_tree(lt, lengths, hlit);
tinf_build_tree(dt, lengths + hlit, hdist);
}
/* ----------------------------- *
* -- block inflate functions -- *
* ----------------------------- */
/* given a stream and two trees, inflate a block of data */
static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
while (1)
{
int sym = tinf_decode_symbol(d, lt);
/* check for end of block */
if (sym == 256)
{
return TINF_OK;
}
if (sym < 256)
{
if (d->destRemaining == 0)
{
int res = tinf_grow_dest_buf(d, 1);
if (res) return res;
}
*d->dest++ = sym;
} else {
int length, dist, offs;
int i;
sym -= 257;
/* possibly get more bits from length code */
length = tinf_read_bits(d, length_bits[sym], length_base[sym]);
dist = tinf_decode_symbol(d, dt);
/* possibly get more bits from distance code */
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
if (d->destRemaining < length)
{
int res = tinf_grow_dest_buf(d, length);
if (res) return res;
}
/* copy match */
for (i = 0; i < length; ++i)
{
d->dest[i] = d->dest[i - offs];
}
d->dest += length;
}
}
}
/* inflate an uncompressed block of data */
static int tinf_inflate_uncompressed_block(TINF_DATA *d)
{
unsigned int length, invlength;
unsigned int i;
/* get length */
length = d->source[1];
length = 256*length + d->source[0];
/* get one's complement of length */
invlength = d->source[3];
invlength = 256*invlength + d->source[2];
/* check length */
if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR;
if (d->destRemaining < length)
{
int res = tinf_grow_dest_buf(d, length);
if (res) return res;
}
d->source += 4;
/* copy block */
for (i = length; i; --i) *d->dest++ = *d->source++;
/* make sure we start next block on a byte boundary */
d->bitcount = 0;
return TINF_OK;
}
/* inflate a block of data compressed with fixed huffman trees */
static int tinf_inflate_fixed_block(TINF_DATA *d)
{
/* build fixed huffman trees */
tinf_build_fixed_trees(&d->ltree, &d->dtree);
/* decode block using fixed trees */
return tinf_inflate_block_data(d, &d->ltree, &d->dtree);
}
/* inflate a block of data compressed with dynamic huffman trees */
static int tinf_inflate_dynamic_block(TINF_DATA *d)
{
/* decode trees from stream */
tinf_decode_trees(d, &d->ltree, &d->dtree);
/* decode block using decoded trees */
return tinf_inflate_block_data(d, &d->ltree, &d->dtree);
}
/* ---------------------- *
* -- public functions -- *
* ---------------------- */
/* initialize global (static) data */
void tinf_init()
{
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
tinf_build_bits_base(length_bits, length_base, 4, 3);
tinf_build_bits_base(dist_bits, dist_base, 2, 1);
/* fix a special case */
length_bits[28] = 0;
length_base[28] = 258;
#endif
}
/* inflate stream from source to dest */
int tinf_uncompress(void *dest, unsigned int *destLen,
const void *source, unsigned int sourceLen)
{
TINF_DATA d;
int res;
/* initialise data */
d.source = (const unsigned char *)source;
d.destStart = (unsigned char *)dest;
d.destRemaining = *destLen;
res = tinf_uncompress_dyn(&d);
*destLen = d.dest - d.destStart;
return res;
}
/* inflate stream from source to dest */
int tinf_uncompress_dyn(TINF_DATA *d)
{
int bfinal;
/* initialise data */
d->bitcount = 0;
d->dest = d->destStart;
d->destRemaining = d->destSize;
do {
unsigned int btype;
int res;
/* read final block flag */
bfinal = tinf_getbit(d);
/* read block type (2 bits) */
btype = tinf_read_bits(d, 2, 0);
/* decompress block */
switch (btype)
{
case 0:
/* decompress uncompressed block */
res = tinf_inflate_uncompressed_block(d);
break;
case 1:
/* decompress block with fixed huffman trees */
res = tinf_inflate_fixed_block(d);
break;
case 2:
/* decompress block with dynamic huffman trees */
res = tinf_inflate_dynamic_block(d);
break;
default:
return TINF_DATA_ERROR;
}
if (res != TINF_OK) return TINF_DATA_ERROR;
} while (!bfinal);
return TINF_OK;
}

101
extmod/uzlib/tinfzlib.c Normal file
View File

@@ -0,0 +1,101 @@
/*
* tinfzlib - tiny zlib decompressor
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include "tinf.h"
int tinf_zlib_uncompress(void *dest, unsigned int *destLen,
const void *source, unsigned int sourceLen)
{
TINF_DATA d;
int res;
/* initialise data */
d.source = (const unsigned char *)source;
d.destStart = (unsigned char *)dest;
d.destRemaining = *destLen;
res = tinf_zlib_uncompress_dyn(&d, sourceLen);
*destLen = d.dest - d.destStart;
return res;
}
int tinf_zlib_uncompress_dyn(TINF_DATA *d, unsigned int sourceLen)
{
unsigned int a32;
int res;
unsigned char cmf, flg;
/* -- get header bytes -- */
cmf = d->source[0];
flg = d->source[1];
/* -- check format -- */
/* check checksum */
if ((256*cmf + flg) % 31) return TINF_DATA_ERROR;
/* check method is deflate */
if ((cmf & 0x0f) != 8) return TINF_DATA_ERROR;
/* check window size is valid */
if ((cmf >> 4) > 7) return TINF_DATA_ERROR;
/* check there is no preset dictionary */
if (flg & 0x20) return TINF_DATA_ERROR;
/* -- get adler32 checksum -- */
a32 = d->source[sourceLen - 4];
a32 = 256*a32 + d->source[sourceLen - 3];
a32 = 256*a32 + d->source[sourceLen - 2];
a32 = 256*a32 + d->source[sourceLen - 1];
d->source += 2;
/* -- inflate -- */
res = tinf_uncompress_dyn(d);
if (res != TINF_OK) return res;
/* -- check adler32 checksum -- */
if (a32 != tinf_adler32(d->destStart, d->dest - d->destStart)) return TINF_DATA_ERROR;
return TINF_OK;
}

2
lib/README.md Normal file
View File

@@ -0,0 +1,2 @@
This directory contains standard, low-level C libraries with emphasis on
being independent and efficient. They can be used by any port.

130
lib/libm/asinfacosf.c Normal file
View File

@@ -0,0 +1,130 @@
/*****************************************************************************/
/*****************************************************************************/
// asinf from musl-0.9.15
/*****************************************************************************/
/*****************************************************************************/
/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
// dpgeorge: pio2 was double in original implementation of asinf
static const float
pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
pio2_lo = 7.5497894159e-08; /* 0x33a22168 */
static const float
/* coefficients for R(x^2) */
pS0 = 1.6666586697e-01,
pS1 = -4.2743422091e-02,
pS2 = -8.6563630030e-03,
qS1 = -7.0662963390e-01;
static float R(float z)
{
float_t p, q;
p = z*(pS0+z*(pS1+z*pS2));
q = 1.0f+z*qS1;
return p/q;
}
float asinf(float x)
{
// dpgeorge: s was double in original implementation
float s,z;
uint32_t hx,ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix >= 0x3f800000) { /* |x| >= 1 */
if (ix == 0x3f800000) /* |x| == 1 */
return x*pio2_hi + 0x1p-120f; /* asin(+-1) = +-pi/2 with inexact */
return 0/(x-x); /* asin(|x|>1) is NaN */
}
if (ix < 0x3f000000) { /* |x| < 0.5 */
/* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */
if (ix < 0x39800000 && ix >= 0x00800000)
return x;
return x + x*R(x*x);
}
/* 1 > |x| >= 0.5 */
z = (1 - fabsf(x))*0.5f;
s = sqrtf(z);
x = pio2_hi - (2*(s+s*R(z)) - pio2_lo); // dpgeorge: use pio2_hi and pio2_lo
if (hx >> 31)
return -x;
return x;
}
/*****************************************************************************/
/*****************************************************************************/
// acosf from musl-0.9.15
/*****************************************************************************/
/*****************************************************************************/
/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
float acosf(float x)
{
float z,w,s,c,df;
uint32_t hx,ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
/* |x| >= 1 or nan */
if (ix >= 0x3f800000) {
if (ix == 0x3f800000) {
if (hx >> 31)
return 2*pio2_hi + 0x1p-120f;
return 0;
}
return 0/(x-x);
}
/* |x| < 0.5 */
if (ix < 0x3f000000) {
if (ix <= 0x32800000) /* |x| < 2**-26 */
return pio2_hi + 0x1p-120f;
return pio2_hi - (x - (pio2_lo-x*R(x*x)));
}
/* x < -0.5 */
if (hx >> 31) {
z = (1+x)*0.5f;
s = sqrtf(z);
w = R(z)*s-pio2_lo;
return 2*(pio2_hi - (s+w));
}
/* x > 0.5 */
z = (1-x)*0.5f;
s = sqrtf(z);
GET_FLOAT_WORD(hx,s);
SET_FLOAT_WORD(df,hx&0xfffff000);
c = (z-df*df)/(s+df);
w = R(z)*s+c;
return 2*(df+w);
}

89
lib/libm/atan2f.c Normal file
View File

@@ -0,0 +1,89 @@
/*****************************************************************************/
/*****************************************************************************/
// atan2f from musl-0.9.15
/*****************************************************************************/
/*****************************************************************************/
/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2f.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
static const float
pi = 3.1415927410e+00, /* 0x40490fdb */
pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */
float atan2f(float y, float x)
{
float z;
uint32_t m,ix,iy;
if (isnan(x) || isnan(y))
return x+y;
GET_FLOAT_WORD(ix, x);
GET_FLOAT_WORD(iy, y);
if (ix == 0x3f800000) /* x=1.0 */
return atanf(y);
m = ((iy>>31)&1) | ((ix>>30)&2); /* 2*sign(x)+sign(y) */
ix &= 0x7fffffff;
iy &= 0x7fffffff;
/* when y = 0 */
if (iy == 0) {
switch (m) {
case 0:
case 1: return y; /* atan(+-0,+anything)=+-0 */
case 2: return pi; /* atan(+0,-anything) = pi */
case 3: return -pi; /* atan(-0,-anything) =-pi */
}
}
/* when x = 0 */
if (ix == 0)
return m&1 ? -pi/2 : pi/2;
/* when x is INF */
if (ix == 0x7f800000) {
if (iy == 0x7f800000) {
switch (m) {
case 0: return pi/4; /* atan(+INF,+INF) */
case 1: return -pi/4; /* atan(-INF,+INF) */
case 2: return 3*pi/4; /*atan(+INF,-INF)*/
case 3: return -3*pi/4; /*atan(-INF,-INF)*/
}
} else {
switch (m) {
case 0: return 0.0f; /* atan(+...,+INF) */
case 1: return -0.0f; /* atan(-...,+INF) */
case 2: return pi; /* atan(+...,-INF) */
case 3: return -pi; /* atan(-...,-INF) */
}
}
}
/* |y/x| > 0x1p26 */
if (ix+(26<<23) < iy || iy == 0x7f800000)
return m&1 ? -pi/2 : pi/2;
/* z = atan(|y/x|) with correct underflow */
if ((m&2) && iy+(26<<23) < ix) /*|y/x| < 0x1p-26, x < 0 */
z = 0.0;
else
z = atanf(fabsf(y/x));
switch (m) {
case 0: return z; /* atan(+,+) */
case 1: return -z; /* atan(-,+) */
case 2: return pi - (z-pi_lo); /* atan(+,-) */
default: /* case 3 */
return (z-pi_lo) - pi; /* atan(-,-) */
}
}

100
lib/libm/atanf.c Normal file
View File

@@ -0,0 +1,100 @@
/*****************************************************************************/
/*****************************************************************************/
// atanf from musl-0.9.15
/*****************************************************************************/
/*****************************************************************************/
/* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
static const float atanhi[] = {
4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
};
static const float atanlo[] = {
5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
};
static const float aT[] = {
3.3333328366e-01,
-1.9999158382e-01,
1.4253635705e-01,
-1.0648017377e-01,
6.1687607318e-02,
};
float atanf(float x)
{
float_t w,s1,s2,z;
uint32_t ix,sign;
int id;
GET_FLOAT_WORD(ix, x);
sign = ix>>31;
ix &= 0x7fffffff;
if (ix >= 0x4c800000) { /* if |x| >= 2**26 */
if (isnan(x))
return x;
z = atanhi[3] + 0x1p-120f;
return sign ? -z : z;
}
if (ix < 0x3ee00000) { /* |x| < 0.4375 */
if (ix < 0x39800000) { /* |x| < 2**-12 */
if (ix < 0x00800000)
/* raise underflow for subnormal x */
FORCE_EVAL(x*x);
return x;
}
id = -1;
} else {
x = fabsf(x);
if (ix < 0x3f980000) { /* |x| < 1.1875 */
if (ix < 0x3f300000) { /* 7/16 <= |x| < 11/16 */
id = 0;
x = (2.0f*x - 1.0f)/(2.0f + x);
} else { /* 11/16 <= |x| < 19/16 */
id = 1;
x = (x - 1.0f)/(x + 1.0f);
}
} else {
if (ix < 0x401c0000) { /* |x| < 2.4375 */
id = 2;
x = (x - 1.5f)/(1.0f + 1.5f*x);
} else { /* 2.4375 <= |x| < 2**26 */
id = 3;
x = -1.0f/x;
}
}
}
/* end of argument reduction */
z = x*x;
w = z*z;
/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
s1 = z*(aT[0]+w*(aT[2]+w*aT[4]));
s2 = w*(aT[1]+w*aT[3]);
if (id < 0)
return x - x*(s1+s2);
z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
return sign ? -z : z;
}

70
lib/libm/fmodf.c Normal file
View File

@@ -0,0 +1,70 @@
/*****************************************************************************/
/*****************************************************************************/
// fmodf from musl-0.9.15
/*****************************************************************************/
/*****************************************************************************/
#include "libm.h"
float fmodf(float x, float y)
{
union {float f; uint32_t i;} ux = {x}, uy = {y};
int ex = ux.i>>23 & 0xff;
int ey = uy.i>>23 & 0xff;
uint32_t sx = ux.i & 0x80000000;
uint32_t i;
uint32_t uxi = ux.i;
if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
return (x*y)/(x*y);
if (uxi<<1 <= uy.i<<1) {
if (uxi<<1 == uy.i<<1)
return 0*x;
return x;
}
/* normalize x and y */
if (!ex) {
for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
uxi <<= -ex + 1;
} else {
uxi &= -1U >> 9;
uxi |= 1U << 23;
}
if (!ey) {
for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
uy.i <<= -ey + 1;
} else {
uy.i &= -1U >> 9;
uy.i |= 1U << 23;
}
/* x mod y */
for (; ex > ey; ex--) {
i = uxi - uy.i;
if (i >> 31 == 0) {
if (i == 0)
return 0*x;
uxi = i;
}
uxi <<= 1;
}
i = uxi - uy.i;
if (i >> 31 == 0) {
if (i == 0)
return 0*x;
uxi = i;
}
for (; uxi>>23 == 0; uxi <<= 1, ex--);
/* scale result up */
if (ex > 0) {
uxi -= 1U << 23;
uxi |= (uint32_t)ex << 23;
} else {
uxi >>= -ex + 1;
}
uxi |= sx;
ux.i = uxi;
return ux.f;
}

52
lib/libm/libm.h Normal file
View File

@@ -0,0 +1,52 @@
/*****************************************************************************/
/*****************************************************************************/
// portions extracted from musl-0.9.15 libm.h
/*****************************************************************************/
/*****************************************************************************/
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include <stdint.h>
#include <math.h>
#define FORCE_EVAL(x) do { \
if (sizeof(x) == sizeof(float)) { \
volatile float __x; \
__x = (x); \
(void)__x; \
} else if (sizeof(x) == sizeof(double)) { \
volatile double __x; \
__x = (x); \
(void)__x; \
} else { \
volatile long double __x; \
__x = (x); \
(void)__x; \
} \
} while(0)
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(w,d) \
do { \
union {float f; uint32_t i;} __u; \
__u.f = (d); \
(w) = __u.i; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,w) \
do { \
union {float f; uint32_t i;} __u; \
__u.i = (w); \
(d) = __u.f; \
} while (0)

View File

@@ -24,8 +24,7 @@
* THE SOFTWARE.
*/
#include <stdint.h>
#include <math.h>
#include "libm.h"
typedef float float_t;
typedef union {
@@ -118,11 +117,6 @@ float acoshf(float x) { return 0.0; }
float asinhf(float x) { return 0.0; }
float atanhf(float x) { return 0.0; }
float tanf(float x) { return 0.0; }
float acosf(float x) { return 0.0; }
float asinf(float x) { return 0.0; }
float atanf(float x) { return 0.0; }
float atan2f(float x, float y) { return 0.0; }
float fmodf(float x, float y) { return 0.0; }
float tgammaf(float x) { return 0.0; }
float lgammaf(float x) { return 0.0; }
float erff(float x) { return 0.0; }
@@ -131,56 +125,6 @@ float modff(float x, float *y) { return 0.0; }
float frexpf(float x, int *exp) { return 0.0; }
float ldexpf(float x, int exp) { return 0.0; }
/*****************************************************************************/
/*****************************************************************************/
// from musl-0.9.15 libm.h
/*****************************************************************************/
/*****************************************************************************/
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#define FORCE_EVAL(x) do { \
if (sizeof(x) == sizeof(float)) { \
volatile float __x; \
__x = (x); \
(void)__x; \
} else if (sizeof(x) == sizeof(double)) { \
volatile double __x; \
__x = (x); \
(void)__x; \
} else { \
volatile long double __x; \
__x = (x); \
(void)__x; \
} \
} while(0)
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(w,d) \
do { \
union {float f; uint32_t i;} __u; \
__u.f = (d); \
(w) = __u.i; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,w) \
do { \
union {float f; uint32_t i;} __u; \
__u.i = (w); \
(d) = __u.f; \
} while (0)
/*****************************************************************************/
/*****************************************************************************/
// __fpclassifyf from musl-0.9.15

View File

@@ -34,7 +34,7 @@
#include "obj.h"
#include "runtime.h"
void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw) {
void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp_uint_t n_args_max, bool takes_kw) {
// TODO maybe take the function name as an argument so we can print nicer error messages
if (n_kw && !takes_kw) {
@@ -60,9 +60,9 @@ void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max,
}
}
void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) {
uint pos_found = 0, kws_found = 0;
for (uint i = 0; i < n_allowed; i++) {
void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_uint_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) {
mp_uint_t pos_found = 0, kws_found = 0;
for (mp_uint_t i = 0; i < n_allowed; i++) {
mp_obj_t given_arg;
if (i < n_pos) {
if (allowed[i].flags & MP_ARG_KW_ONLY) {
@@ -104,7 +104,7 @@ void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_all
}
}
void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) {
void mp_arg_parse_all_kw_array(mp_uint_t n_pos, mp_uint_t n_kw, const mp_obj_t *args, mp_uint_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) {
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_pos);
mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals);

439
py/asmarm.c Normal file
View File

@@ -0,0 +1,439 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Fabian Vogt
* Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "mpconfig.h"
#include "misc.h"
#include "asmarm.h"
// wrapper around everything in this file
#if MICROPY_EMIT_ARM
#define SIGNED_FIT24(x) (((x) & 0xff800000) == 0) || (((x) & 0xff000000) == 0xff000000)
struct _asm_arm_t {
uint pass;
mp_uint_t code_offset;
mp_uint_t code_size;
byte *code_base;
byte dummy_data[4];
mp_uint_t max_num_labels;
mp_uint_t *label_offsets;
uint push_reglist;
uint stack_adjust;
};
asm_arm_t *asm_arm_new(uint max_num_labels) {
asm_arm_t *as;
as = m_new0(asm_arm_t, 1);
as->max_num_labels = max_num_labels;
as->label_offsets = m_new(mp_uint_t, max_num_labels);
return as;
}
void asm_arm_free(asm_arm_t *as, bool free_code) {
if (free_code) {
MP_PLAT_FREE_EXEC(as->code_base, as->code_size);
}
m_del(mp_uint_t, as->label_offsets, as->max_num_labels);
m_del_obj(asm_arm_t, as);
}
void asm_arm_start_pass(asm_arm_t *as, uint pass) {
as->pass = pass;
as->code_offset = 0;
if (pass == ASM_ARM_PASS_COMPUTE) {
memset(as->label_offsets, -1, as->max_num_labels * sizeof(mp_uint_t));
}
}
void asm_arm_end_pass(asm_arm_t *as) {
if (as->pass == ASM_ARM_PASS_COMPUTE) {
MP_PLAT_ALLOC_EXEC(as->code_offset, (void**) &as->code_base, &as->code_size);
if(as->code_base == NULL) {
assert(0);
}
} else if(as->pass == ASM_ARM_PASS_EMIT) {
#ifdef __arm__
// flush I- and D-cache
asm volatile(
"0:"
"mrc p15, 0, r15, c7, c10, 3\n"
"bne 0b\n"
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c7, 0\n"
: : : "r0", "cc");
#endif
}
}
// all functions must go through this one to emit bytes
// if as->pass < ASM_ARM_PASS_EMIT, then this function only returns a buffer of 4 bytes length
STATIC byte *asm_arm_get_cur_to_write_bytes(asm_arm_t *as, int num_bytes_to_write) {
if (as->pass < ASM_ARM_PASS_EMIT) {
as->code_offset += num_bytes_to_write;
return as->dummy_data;
} else {
assert(as->code_offset + num_bytes_to_write <= as->code_size);
byte *c = as->code_base + as->code_offset;
as->code_offset += num_bytes_to_write;
return c;
}
}
uint asm_arm_get_code_size(asm_arm_t *as) {
return as->code_size;
}
void *asm_arm_get_code(asm_arm_t *as) {
return as->code_base;
}
// Insert word into instruction flow
STATIC void emit(asm_arm_t *as, uint op) {
*(uint*)asm_arm_get_cur_to_write_bytes(as, 4) = op;
}
// Insert word into instruction flow, add "ALWAYS" condition code
STATIC void emit_al(asm_arm_t *as, uint op) {
emit(as, op | ASM_ARM_CC_AL);
}
// Basic instructions without condition code
STATIC uint asm_arm_op_push(uint reglist) {
// stmfd sp!, {reglist}
return 0x92d0000 | (reglist & 0xFFFF);
}
STATIC uint asm_arm_op_pop(uint reglist) {
// ldmfd sp!, {reglist}
return 0x8bd0000 | (reglist & 0xFFFF);
}
STATIC uint asm_arm_op_mov_reg(uint rd, uint rn) {
// mov rd, rn
return 0x1a00000 | (rd << 12) | rn;
}
STATIC uint asm_arm_op_mov_imm(uint rd, uint imm) {
// mov rd, #imm
return 0x3a00000 | (rd << 12) | imm;
}
STATIC uint asm_arm_op_mvn_imm(uint rd, uint imm) {
// mvn rd, #imm
return 0x3e00000 | (rd << 12) | imm;
}
STATIC uint asm_arm_op_add_imm(uint rd, uint rn, uint imm) {
// add rd, rn, #imm
return 0x2800000 | (rn << 16) | (rd << 12) | (imm & 0xFF);
}
STATIC uint asm_arm_op_add_reg(uint rd, uint rn, uint rm) {
// add rd, rn, rm
return 0x0800000 | (rn << 16) | (rd << 12) | rm;
}
STATIC uint asm_arm_op_sub_imm(uint rd, uint rn, uint imm) {
// sub rd, rn, #imm
return 0x2400000 | (rn << 16) | (rd << 12) | (imm & 0xFF);
}
STATIC uint asm_arm_op_sub_reg(uint rd, uint rn, uint rm) {
// sub rd, rn, rm
return 0x0400000 | (rn << 16) | (rd << 12) | rm;
}
STATIC uint asm_arm_op_and_reg(uint rd, uint rn, uint rm) {
// and rd, rn, rm
return 0x0000000 | (rn << 16) | (rd << 12) | rm;
}
STATIC uint asm_arm_op_eor_reg(uint rd, uint rn, uint rm) {
// eor rd, rn, rm
return 0x0200000 | (rn << 16) | (rd << 12) | rm;
}
STATIC uint asm_arm_op_orr_reg(uint rd, uint rn, uint rm) {
// orr rd, rn, rm
return 0x1800000 | (rn << 16) | (rd << 12) | rm;
}
void asm_arm_bkpt(asm_arm_t *as) {
// bkpt #0
emit_al(as, 0x1200070);
}
// locals:
// - stored on the stack in ascending order
// - numbered 0 through num_locals-1
// - SP points to first local
//
// | SP
// v
// l0 l1 l2 ... l(n-1)
// ^ ^
// | low address | high address in RAM
void asm_arm_entry(asm_arm_t *as, int num_locals) {
if (num_locals < 0) {
num_locals = 0;
}
as->stack_adjust = 0;
as->push_reglist = 1 << ASM_ARM_REG_R1
| 1 << ASM_ARM_REG_R2
| 1 << ASM_ARM_REG_R3
| 1 << ASM_ARM_REG_R4
| 1 << ASM_ARM_REG_R5
| 1 << ASM_ARM_REG_R6
| 1 << ASM_ARM_REG_R7
| 1 << ASM_ARM_REG_R8;
// Only adjust the stack if there are more locals than usable registers
if(num_locals > 3) {
as->stack_adjust = num_locals * 4;
// Align stack to 8 bytes
if (num_locals & 1) {
as->stack_adjust += 4;
}
}
emit_al(as, asm_arm_op_push(as->push_reglist | 1 << ASM_ARM_REG_LR));
if (as->stack_adjust > 0) {
emit_al(as, asm_arm_op_sub_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust));
}
}
void asm_arm_exit(asm_arm_t *as) {
if (as->stack_adjust > 0) {
emit_al(as, asm_arm_op_add_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust));
}
emit_al(as, asm_arm_op_pop(as->push_reglist | (1 << ASM_ARM_REG_PC)));
}
void asm_arm_label_assign(asm_arm_t *as, uint label) {
assert(label < as->max_num_labels);
if (as->pass < ASM_ARM_PASS_EMIT) {
// assign label offset
assert(as->label_offsets[label] == -1);
as->label_offsets[label] = as->code_offset;
} else {
// ensure label offset has not changed from PASS_COMPUTE to PASS_EMIT
assert(as->label_offsets[label] == as->code_offset);
}
}
void asm_arm_align(asm_arm_t* as, uint align) {
// TODO fill unused data with NOPs?
as->code_offset = (as->code_offset + align - 1) & (~(align - 1));
}
void asm_arm_data(asm_arm_t* as, uint bytesize, uint val) {
byte *c = asm_arm_get_cur_to_write_bytes(as, bytesize);
// only write to the buffer in the emit pass (otherwise we overflow dummy_data)
if (as->pass == ASM_ARM_PASS_EMIT) {
// little endian
for (uint i = 0; i < bytesize; i++) {
*c++ = val;
val >>= 8;
}
}
}
void asm_arm_mov_reg_reg(asm_arm_t *as, uint reg_dest, uint reg_src) {
emit_al(as, asm_arm_op_mov_reg(reg_dest, reg_src));
}
void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) {
// TODO: There are more variants of immediate values
if ((imm & 0xFF) == imm) {
emit_al(as, asm_arm_op_mov_imm(rd, imm));
} else if (imm < 0 && ((-imm) & 0xFF) == -imm) {
emit_al(as, asm_arm_op_mvn_imm(rd, -imm));
} else {
//Insert immediate into code and jump over it
emit_al(as, 0x59f0000 | (rd << 12)); // ldr rd, [pc]
emit_al(as, 0xa000000); // b pc
emit(as, imm);
}
}
void asm_arm_mov_local_reg(asm_arm_t *as, int local_num, uint rd) {
// str rd, [sp, #local_num*4]
emit_al(as, 0x58d0000 | (rd << 12) | (local_num << 2));
}
void asm_arm_mov_reg_local(asm_arm_t *as, uint rd, int local_num) {
// ldr rd, [sp, #local_num*4]
emit_al(as, 0x59d0000 | (rd << 12) | (local_num << 2));
}
void asm_arm_cmp_reg_i8(asm_arm_t *as, uint rd, int imm) {
// cmp rd, #imm
emit_al(as, 0x3500000 | (rd << 16) | (imm & 0xFF));
}
void asm_arm_cmp_reg_reg(asm_arm_t *as, uint rd, uint rn) {
// cmp rd, rn
emit_al(as, 0x1500000 | (rd << 16) | rn);
}
void asm_arm_setcc_reg(asm_arm_t *as, uint rd, uint cond) {
emit(as, asm_arm_op_mov_imm(rd, 1) | cond); // movCOND rd, #1
emit(as, asm_arm_op_mov_imm(rd, 0) | (cond ^ (1 << 28))); // mov!COND rd, #0
}
void asm_arm_add_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
// add rd, rn, rm
emit_al(as, asm_arm_op_add_reg(rd, rn, rm));
}
void asm_arm_sub_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
// sub rd, rn, rm
emit_al(as, asm_arm_op_sub_reg(rd, rn, rm));
}
void asm_arm_and_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
// and rd, rn, rm
emit_al(as, asm_arm_op_and_reg(rd, rn, rm));
}
void asm_arm_eor_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
// eor rd, rn, rm
emit_al(as, asm_arm_op_eor_reg(rd, rn, rm));
}
void asm_arm_orr_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
// orr rd, rn, rm
emit_al(as, asm_arm_op_orr_reg(rd, rn, rm));
}
void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num) {
// add rd, sp, #local_num*4
emit_al(as, asm_arm_op_add_imm(rd, ASM_ARM_REG_SP, local_num << 2));
}
void asm_arm_lsl_reg_reg(asm_arm_t *as, uint rd, uint rs) {
// mov rd, rd, lsl rs
emit_al(as, 0x1a00010 | (rd << 12) | (rs << 8) | rd);
}
void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs) {
// mov rd, rd, asr rs
emit_al(as, 0x1a00050 | (rd << 12) | (rs << 8) | rd);
}
void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn) {
// ldr rd, [rn]
emit_al(as, 0x5900000 | (rn << 16) | (rd << 12));
}
void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn) {
// ldrh rd, [rn]
emit_al(as, 0x1d000b0 | (rn << 16) | (rd << 12));
}
void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn) {
// ldrb rd, [rn]
emit_al(as, 0x5d00000 | (rn << 16) | (rd << 12));
}
void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm) {
// str rd, [rm]
emit_al(as, 0x5800000 | (rm << 16) | (rd << 12));
}
void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm) {
// strh rd, [rm]
emit_al(as, 0x1c000b0 | (rm << 16) | (rd << 12));
}
void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm) {
// strb rd, [rm]
emit_al(as, 0x5c00000 | (rm << 16) | (rd << 12));
}
void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
// str rd, [rm, rn, lsl #2]
emit_al(as, 0x7800100 | (rm << 16) | (rd << 12) | rn);
}
void asm_arm_strh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
// strh doesn't support scaled register index
emit_al(as, 0x1a00080 | (ASM_ARM_REG_R8 << 12) | rn); // mov r8, rn, lsl #1
emit_al(as, 0x18000b0 | (rm << 16) | (rd << 12) | ASM_ARM_REG_R8); // strh rd, [rm, r8]
}
void asm_arm_strb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
// strb rd, [rm, rn]
emit_al(as, 0x7c00000 | (rm << 16) | (rd << 12) | rn);
}
void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label) {
assert(label < as->max_num_labels);
mp_uint_t dest = as->label_offsets[label];
mp_int_t rel = dest - as->code_offset;
rel -= 8; // account for instruction prefetch, PC is 8 bytes ahead of this instruction
rel >>= 2; // in ARM mode the branch target is 32-bit aligned, so the 2 LSB are omitted
if (SIGNED_FIT24(rel)) {
emit(as, cond | 0xa000000 | (rel & 0xffffff));
} else {
printf("asm_arm_bcc: branch does not fit in 24 bits\n");
}
}
void asm_arm_b_label(asm_arm_t *as, uint label) {
asm_arm_bcc_label(as, ASM_ARM_CC_AL, label);
}
void asm_arm_bl_ind(asm_arm_t *as, void *fun_ptr, uint fun_id, uint reg_temp) {
// If the table offset fits into the ldr instruction
if(fun_id < (0x1000 / 4)) {
emit_al(as, asm_arm_op_mov_reg(ASM_ARM_REG_LR, ASM_ARM_REG_PC)); // mov lr, pc
emit_al(as, 0x597f000 | (fun_id << 2)); // ldr pc, [r7, #fun_id*4]
return;
}
emit_al(as, 0x59f0004 | (reg_temp << 12)); // ldr rd, [pc, #4]
// Set lr after fun_ptr
emit_al(as, asm_arm_op_add_imm(ASM_ARM_REG_LR, ASM_ARM_REG_PC, 4)); // add lr, pc, #4
emit_al(as, asm_arm_op_mov_reg(ASM_ARM_REG_PC, reg_temp)); // mov pc, reg_temp
emit(as, (uint) fun_ptr);
}
#endif // MICROPY_EMIT_ARM

122
py/asmarm.h Normal file
View File

@@ -0,0 +1,122 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Fabian Vogt
* 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.
*/
#define ASM_ARM_PASS_COMPUTE (1)
#define ASM_ARM_PASS_EMIT (2)
#define ASM_ARM_REG_R0 (0)
#define ASM_ARM_REG_R1 (1)
#define ASM_ARM_REG_R2 (2)
#define ASM_ARM_REG_R3 (3)
#define ASM_ARM_REG_R4 (4)
#define ASM_ARM_REG_R5 (5)
#define ASM_ARM_REG_R6 (6)
#define ASM_ARM_REG_R7 (7)
#define ASM_ARM_REG_R8 (8)
#define ASM_ARM_REG_R9 (9)
#define ASM_ARM_REG_R10 (10)
#define ASM_ARM_REG_R11 (11)
#define ASM_ARM_REG_R12 (12)
#define ASM_ARM_REG_R13 (13)
#define ASM_ARM_REG_R14 (14)
#define ASM_ARM_REG_R15 (15)
#define ASM_ARM_REG_SP (ASM_ARM_REG_R13)
#define ASM_ARM_REG_LR (ASM_ARM_REG_R14)
#define ASM_ARM_REG_PC (ASM_ARM_REG_R15)
#define ASM_ARM_CC_EQ (0x0 << 28)
#define ASM_ARM_CC_NE (0x1 << 28)
#define ASM_ARM_CC_CS (0x2 << 28)
#define ASM_ARM_CC_CC (0x3 << 28)
#define ASM_ARM_CC_MI (0x4 << 28)
#define ASM_ARM_CC_PL (0x5 << 28)
#define ASM_ARM_CC_VS (0x6 << 28)
#define ASM_ARM_CC_VC (0x7 << 28)
#define ASM_ARM_CC_HI (0x8 << 28)
#define ASM_ARM_CC_LS (0x9 << 28)
#define ASM_ARM_CC_GE (0xa << 28)
#define ASM_ARM_CC_LT (0xb << 28)
#define ASM_ARM_CC_GT (0xc << 28)
#define ASM_ARM_CC_LE (0xd << 28)
#define ASM_ARM_CC_AL (0xe << 28)
typedef struct _asm_arm_t asm_arm_t;
asm_arm_t *asm_arm_new(uint max_num_labels);
void asm_arm_free(asm_arm_t *as, bool free_code);
void asm_arm_start_pass(asm_arm_t *as, uint pass);
void asm_arm_end_pass(asm_arm_t *as);
uint asm_arm_get_code_size(asm_arm_t *as);
void *asm_arm_get_code(asm_arm_t *as);
void asm_arm_entry(asm_arm_t *as, int num_locals);
void asm_arm_exit(asm_arm_t *as);
void asm_arm_label_assign(asm_arm_t *as, uint label);
void asm_arm_align(asm_arm_t* as, uint align);
void asm_arm_data(asm_arm_t* as, uint bytesize, uint val);
void asm_arm_bkpt(asm_arm_t *as);
// mov
void asm_arm_mov_reg_reg(asm_arm_t *as, uint reg_dest, uint reg_src);
void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm);
void asm_arm_mov_local_reg(asm_arm_t *as, int local_num, uint rd);
void asm_arm_mov_reg_local(asm_arm_t *as, uint rd, int local_num);
void asm_arm_setcc_reg(asm_arm_t *as, uint rd, uint cond);
// compare
void asm_arm_cmp_reg_i8(asm_arm_t *as, uint rd, int imm);
void asm_arm_cmp_reg_reg(asm_arm_t *as, uint rd, uint rn);
// arithmetic
void asm_arm_add_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
void asm_arm_sub_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
void asm_arm_and_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
void asm_arm_eor_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
void asm_arm_orr_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num);
void asm_arm_lsl_reg_reg(asm_arm_t *as, uint rd, uint rs);
void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs);
// memory
void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn);
void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn);
void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn);
void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm);
void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm);
void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm);
// store to array
void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn);
void asm_arm_strh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn);
void asm_arm_strb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn);
// control flow
void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label);
void asm_arm_b_label(asm_arm_t *as, uint label);
void asm_arm_bl_ind(asm_arm_t *as, void *fun_ptr, uint fun_id, uint reg_temp);

View File

@@ -42,17 +42,16 @@
#define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800)
struct _asm_thumb_t {
uint pass;
uint code_offset;
uint code_size;
mp_uint_t pass;
mp_uint_t code_offset;
mp_uint_t code_size;
byte *code_base;
byte dummy_data[4];
uint max_num_labels;
int *label_offsets;
int num_locals;
uint push_reglist;
uint stack_adjust;
mp_uint_t max_num_labels;
mp_uint_t *label_offsets;
mp_uint_t push_reglist;
mp_uint_t stack_adjust;
};
asm_thumb_t *asm_thumb_new(uint max_num_labels) {
@@ -60,27 +59,16 @@ asm_thumb_t *asm_thumb_new(uint max_num_labels) {
as = m_new0(asm_thumb_t, 1);
as->max_num_labels = max_num_labels;
as->label_offsets = m_new(int, max_num_labels);
as->label_offsets = m_new(mp_uint_t, max_num_labels);
return as;
}
void asm_thumb_free(asm_thumb_t *as, bool free_code) {
if (free_code) {
m_del(byte, as->code_base, as->code_size);
MP_PLAT_FREE_EXEC(as->code_base, as->code_size);
}
/*
if (as->label != NULL) {
int i;
for (i = 0; i < as->label->len; ++i)
{
Label *lab = &g_array_index(as->label, Label, i);
if (lab->unresolved != NULL)
g_array_free(lab->unresolved, true);
}
g_array_free(as->label, true);
}
*/
m_del(mp_uint_t, as->label_offsets, as->max_num_labels);
m_del_obj(asm_thumb_t, as);
}
@@ -88,15 +76,16 @@ void asm_thumb_start_pass(asm_thumb_t *as, uint pass) {
as->pass = pass;
as->code_offset = 0;
if (pass == ASM_THUMB_PASS_COMPUTE) {
memset(as->label_offsets, -1, as->max_num_labels * sizeof(int));
memset(as->label_offsets, -1, as->max_num_labels * sizeof(mp_uint_t));
}
}
void asm_thumb_end_pass(asm_thumb_t *as) {
if (as->pass == ASM_THUMB_PASS_COMPUTE) {
// calculate size of code in bytes
as->code_size = as->code_offset;
as->code_base = m_new(byte, as->code_size);
MP_PLAT_ALLOC_EXEC(as->code_offset, (void**) &as->code_base, &as->code_size);
if(as->code_base == NULL) {
assert(0);
}
//printf("code_size: %u\n", as->code_size);
}
@@ -132,8 +121,7 @@ uint asm_thumb_get_code_size(asm_thumb_t *as) {
}
void *asm_thumb_get_code(asm_thumb_t *as) {
// need to set low bit to indicate that it's thumb code
return (void *)(((mp_uint_t)as->code_base) | 1);
return as->code_base;
}
/*
@@ -169,7 +157,7 @@ STATIC void asm_thumb_write_word32(asm_thumb_t *as, int w32) {
// locals:
// - stored on the stack in ascending order
// - numbered 0 through as->num_locals-1
// - numbered 0 through num_locals-1
// - SP points to first local
//
// | SP
@@ -222,7 +210,6 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) {
}
as->push_reglist = reglist;
as->stack_adjust = stack_adjust;
as->num_locals = num_locals;
}
void asm_thumb_exit(asm_thumb_t *as) {
@@ -262,7 +249,7 @@ void asm_thumb_data(asm_thumb_t* as, uint bytesize, uint val) {
}
}
STATIC int get_label_dest(asm_thumb_t *as, uint label) {
STATIC mp_uint_t get_label_dest(asm_thumb_t *as, uint label) {
assert(label < as->max_num_labels);
return as->label_offsets[label];
}
@@ -286,23 +273,23 @@ void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2) {
#define OP_FORMAT_2(op, rlo_dest, rlo_src, src_b) ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest))
void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b) {
assert(rlo_dest < REG_R8);
assert(rlo_src < REG_R8);
assert(rlo_dest < ASM_THUMB_REG_R8);
assert(rlo_src < ASM_THUMB_REG_R8);
asm_thumb_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b));
}
#define OP_FORMAT_3(op, rlo, i8) ((op) | ((rlo) << 8) | (i8))
void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) {
assert(rlo < REG_R8);
assert(rlo < ASM_THUMB_REG_R8);
asm_thumb_op16(as, OP_FORMAT_3(op, rlo, i8));
}
#define OP_FORMAT_4(op, rlo_dest, rlo_src) ((op) | ((rlo_src) << 3) | (rlo_dest))
void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) {
assert(rlo_dest < REG_R8);
assert(rlo_src < REG_R8);
assert(rlo_dest < ASM_THUMB_REG_R8);
assert(rlo_src < ASM_THUMB_REG_R8);
asm_thumb_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src));
}
@@ -333,7 +320,7 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) {
// if loading lo half with movw, the i16 value will be zero extended into the r32 register!
STATIC void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) {
assert(reg_dest < REG_R15);
assert(reg_dest < ASM_THUMB_REG_R15);
// mov[wt] reg_dest, #i16_src
asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff));
}
@@ -348,15 +335,11 @@ void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) {
asm_thumb_mov_reg_i16(as, OP_MOVT, reg_dest, i16_src);
}
void asm_thumb_ite_ge(asm_thumb_t *as) {
asm_thumb_op16(as, 0xbfac);
}
#define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff))
void asm_thumb_b_n(asm_thumb_t *as, uint label) {
int dest = get_label_dest(as, label);
int rel = dest - as->code_offset;
mp_uint_t dest = get_label_dest(as, label);
mp_int_t rel = dest - as->code_offset;
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
if (SIGNED_FIT12(rel)) {
asm_thumb_op16(as, OP_B_N(rel));
@@ -368,8 +351,8 @@ void asm_thumb_b_n(asm_thumb_t *as, uint label) {
#define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff))
void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label) {
int dest = get_label_dest(as, label);
int rel = dest - as->code_offset;
mp_uint_t dest = get_label_dest(as, label);
mp_int_t rel = dest - as->code_offset;
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
if (SIGNED_FIT9(rel)) {
asm_thumb_op16(as, OP_BCC_N(cond, rel));
@@ -415,14 +398,14 @@ void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32) {
#define OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset) (0x9800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num, uint rlo_src) {
assert(rlo_src < REG_R8);
assert(rlo_src < ASM_THUMB_REG_R8);
int word_offset = local_num;
assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset));
}
void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
assert(rlo_dest < REG_R8);
assert(rlo_dest < ASM_THUMB_REG_R8);
int word_offset = local_num;
assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset));
@@ -431,7 +414,7 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
#define OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset) (0xa800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num) {
assert(rlo_dest < REG_R8);
assert(rlo_dest < ASM_THUMB_REG_R8);
int word_offset = local_num;
assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset));
@@ -442,10 +425,10 @@ void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num)
#define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
void asm_thumb_b_label(asm_thumb_t *as, uint label) {
int dest = get_label_dest(as, label);
int rel = dest - as->code_offset;
mp_uint_t dest = get_label_dest(as, label);
mp_int_t rel = dest - as->code_offset;
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
if (dest >= 0 && rel <= -4) {
if (dest != -1 && rel <= -4) {
// is a backwards jump, so we know the size of the jump on the first pass
// calculate rel assuming 12 bit relative jump
if (SIGNED_FIT12(rel)) {
@@ -465,10 +448,10 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) {
#define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff))
void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) {
int dest = get_label_dest(as, label);
int rel = dest - as->code_offset;
mp_uint_t dest = get_label_dest(as, label);
mp_int_t rel = dest - as->code_offset;
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
if (dest >= 0 && rel <= -4) {
if (dest != -1 && rel <= -4) {
// is a backwards jump, so we know the size of the jump on the first pass
// calculate rel assuming 9 bit relative jump
if (SIGNED_FIT9(rel)) {
@@ -488,25 +471,22 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) {
void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp) {
/* TODO make this use less bytes
uint rlo_base = REG_R3;
uint rlo_dest = REG_R7;
uint rlo_base = ASM_THUMB_REG_R3;
uint rlo_dest = ASM_THUMB_REG_R7;
uint word_offset = 4;
asm_thumb_op16(as, 0x0000);
asm_thumb_op16(as, 0x6800 | (word_offset << 6) | (rlo_base << 3) | rlo_dest); // ldr rlo_dest, [rlo_base, #offset]
asm_thumb_op16(as, 0x4780 | (REG_R9 << 3)); // blx reg
asm_thumb_op16(as, 0x4780 | (ASM_THUMB_REG_R9 << 3)); // blx reg
*/
if (0) {
// load ptr to function into register using immediate, then branch
// not relocatable
asm_thumb_mov_reg_i32(as, reg_temp, (mp_uint_t)fun_ptr);
asm_thumb_op16(as, OP_BLX(reg_temp));
} else if (1) {
asm_thumb_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, REG_R7, fun_id));
if (fun_id < 32) {
// load ptr to function from table, indexed by fun_id (must be in range 0-31); 4 bytes
asm_thumb_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, ASM_THUMB_REG_R7, fun_id));
asm_thumb_op16(as, OP_BLX(reg_temp));
} else {
// use SVC
asm_thumb_op16(as, OP_SVC(fun_id));
// load ptr to function into register using immediate; 6 bytes
asm_thumb_mov_reg_i32(as, reg_temp, (mp_uint_t)fun_ptr);
asm_thumb_op16(as, OP_BLX(reg_temp));
}
}

Some files were not shown because too many files have changed in this diff Show More